Commit 1c7c2cde authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (63 commits)
  ide: remove REQ_TYPE_ATA_CMD
  ide: switch ide_cmd_ioctl() to use REQ_TYPE_ATA_TASKFILE requests
  ide: switch set_xfer_rate() to use REQ_TYPE_ATA_TASKFILE requests
  ide: fix final status check in drive_cmd_intr()
  ide: check BUSY and ERROR status bits before reading data in drive_cmd_intr()
  ide: don't enable local IRQs for PIO-in in driver_cmd_intr() (take 2)
  ide: convert "empty" REQ_TYPE_ATA_CMD requests to use REQ_TYPE_ATA_TASKFILE
  ide: initialize rq->cmd_type in ide_init_drive_cmd() callers
  ide: use wait_drive_not_busy() in drive_cmd_intr() (take 2)
  ide: kill DATA_READY define
  ide: task_end_request() fix
  ide: use rq->nr_sectors in task_end_request()
  ide: remove needless ->cursg clearing from task_end_request()
  ide: set IDE_TFLAG_IN_* flags before queuing/executing command
  ide-tape: fix handling of non-special requests in ->end_request method
  ide: fix final status check in task_in_intr()
  ide: clear HOB bit for REQ_TYPE_ATA_CMD requests in ide_end_drive_cmd()
  ide: fix ->io_32bit race in ide_taskfile_ioctl()
  cmd64x: remove /proc/ide/cmd64x
  ide: remove broken disk byte-swapping support
  ...
parents 0444fa78 7267c337
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
*** ***
*** The CMD640 is also used on some Vesa Local Bus (VLB) cards, and is *NOT* *** The CMD640 is also used on some Vesa Local Bus (VLB) cards, and is *NOT*
*** automatically detected by Linux. For safe, reliable operation with such *** automatically detected by Linux. For safe, reliable operation with such
*** interfaces, one *MUST* use the "ide0=cmd640_vlb" kernel option. *** interfaces, one *MUST* use the "cmd640.probe_vlb" kernel option.
*** ***
*** Use of the "serialize" option is no longer necessary. *** Use of the "serialize" option is no longer necessary.
...@@ -244,10 +244,6 @@ Summary of ide driver parameters for kernel command line ...@@ -244,10 +244,6 @@ Summary of ide driver parameters for kernel command line
"hdx=nodma" : disallow DMA "hdx=nodma" : disallow DMA
"hdx=swapdata" : when the drive is a disk, byte swap all data
"hdx=bswap" : same as above..........
"hdx=scsi" : the return of the ide-scsi flag, this is useful for "hdx=scsi" : the return of the ide-scsi flag, this is useful for
allowing ide-floppy, ide-tape, and ide-cdrom|writers allowing ide-floppy, ide-tape, and ide-cdrom|writers
to use ide-scsi emulation on a device specific option. to use ide-scsi emulation on a device specific option.
...@@ -292,9 +288,6 @@ The following are valid ONLY on ide0, which usually corresponds ...@@ -292,9 +288,6 @@ The following are valid ONLY on ide0, which usually corresponds
to the first ATA interface found on the particular host, and the defaults for to the first ATA interface found on the particular host, and the defaults for
the base,ctl ports must not be altered. the base,ctl ports must not be altered.
"ide0=cmd640_vlb" : *REQUIRED* for VLB cards with the CMD640 chip
(not for PCI -- automatically detected)
"ide=doubler" : probe/support IDE doublers on Amiga "ide=doubler" : probe/support IDE doublers on Amiga
There may be more options than shown -- use the source, Luke! There may be more options than shown -- use the source, Luke!
...@@ -310,6 +303,10 @@ i.e. to enable probing for ALI M14xx chipsets (ali14xx host driver) use: ...@@ -310,6 +303,10 @@ i.e. to enable probing for ALI M14xx chipsets (ali14xx host driver) use:
* "probe" module parameter when ali14xx driver is compiled as module * "probe" module parameter when ali14xx driver is compiled as module
("modprobe ali14xx probe") ("modprobe ali14xx probe")
Also for legacy CMD640 host driver (cmd640) you need to use "probe_vlb"
kernel paremeter to enable probing for VLB version of the chipset (PCI ones
are detected automatically).
================================================================================ ================================================================================
IDE ATAPI streaming tape driver IDE ATAPI streaming tape driver
......
...@@ -325,7 +325,7 @@ config BLK_DEV_PLATFORM ...@@ -325,7 +325,7 @@ config BLK_DEV_PLATFORM
If unsure, say N. If unsure, say N.
config BLK_DEV_CMD640 config BLK_DEV_CMD640
bool "CMD640 chipset bugfix/support" tristate "CMD640 chipset bugfix/support"
depends on X86 depends on X86
---help--- ---help---
The CMD-Technologies CMD640 IDE chip is used on many common 486 and The CMD-Technologies CMD640 IDE chip is used on many common 486 and
...@@ -359,9 +359,8 @@ config BLK_DEV_CMD640_ENHANCED ...@@ -359,9 +359,8 @@ config BLK_DEV_CMD640_ENHANCED
Otherwise say N. Otherwise say N.
config BLK_DEV_IDEPNP config BLK_DEV_IDEPNP
bool "PNP EIDE support" tristate "PNP EIDE support"
depends on PNP depends on PNP
select IDE_GENERIC
help help
If you have a PnP (Plug and Play) compatible EIDE card and If you have a PnP (Plug and Play) compatible EIDE card and
would like the kernel to automatically detect and activate would like the kernel to automatically detect and activate
...@@ -375,7 +374,19 @@ config BLK_DEV_IDEPCI ...@@ -375,7 +374,19 @@ config BLK_DEV_IDEPCI
bool bool
config IDEPCI_PCIBUS_ORDER config IDEPCI_PCIBUS_ORDER
def_bool BLK_DEV_IDE=y && BLK_DEV_IDEPCI bool "Probe IDE PCI devices in the PCI bus order (DEPRECATED)"
depends on BLK_DEV_IDE=y && BLK_DEV_IDEPCI
default y
help
Probe IDE PCI devices in the order in which they appear on the
PCI bus (i.e. 00:1f.1 PCI device before 02:01.0 PCI device)
instead of the order in which IDE PCI host drivers are loaded.
Please note that this method of assuring stable naming of
IDE devices is unreliable and use other means for achieving
it (i.e. udev).
If in doubt, say N.
# TODO: split it on per host driver config options (or module parameters) # TODO: split it on per host driver config options (or module parameters)
config BLK_DEV_OFFBOARD config BLK_DEV_OFFBOARD
...@@ -789,7 +800,7 @@ config BLK_DEV_CELLEB ...@@ -789,7 +800,7 @@ config BLK_DEV_CELLEB
endif endif
config BLK_DEV_IDE_PMAC config BLK_DEV_IDE_PMAC
bool "Builtin PowerMac IDE support" tristate "Builtin PowerMac IDE support"
depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y
help help
This driver provides support for the built-in IDE controller on This driver provides support for the built-in IDE controller on
...@@ -843,8 +854,9 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ ...@@ -843,8 +854,9 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
depends on BLK_DEV_IDE_AU1XXX depends on BLK_DEV_IDE_AU1XXX
config IDE_ARM config IDE_ARM
def_bool ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) tristate "ARM IDE support"
select IDE_GENERIC depends on ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK)
default y
config BLK_DEV_IDE_ICSIDE config BLK_DEV_IDE_ICSIDE
tristate "ICS IDE interface support" tristate "ICS IDE interface support"
...@@ -876,10 +888,9 @@ config BLK_DEV_IDE_BAST ...@@ -876,10 +888,9 @@ config BLK_DEV_IDE_BAST
Simtec BAST or the Thorcom VR1000 Simtec BAST or the Thorcom VR1000
config ETRAX_IDE config ETRAX_IDE
bool "ETRAX IDE support" tristate "ETRAX IDE support"
depends on CRIS && BROKEN depends on CRIS && BROKEN
select BLK_DEV_IDEDMA select BLK_DEV_IDEDMA
select IDE_GENERIC
help help
Enables the ETRAX IDE driver. Enables the ETRAX IDE driver.
...@@ -911,17 +922,15 @@ config ETRAX_IDE_G27_RESET ...@@ -911,17 +922,15 @@ config ETRAX_IDE_G27_RESET
endchoice endchoice
config IDE_H8300 config IDE_H8300
bool "H8300 IDE support" tristate "H8300 IDE support"
depends on H8300 depends on H8300
select IDE_GENERIC
default y default y
help help
Enables the H8300 IDE driver. Enables the H8300 IDE driver.
config BLK_DEV_GAYLE config BLK_DEV_GAYLE
bool "Amiga Gayle IDE interface support" tristate "Amiga Gayle IDE interface support"
depends on AMIGA depends on AMIGA
select IDE_GENERIC
help help
This is the IDE driver for the Amiga Gayle IDE interface. It supports This is the IDE driver for the Amiga Gayle IDE interface. It supports
both the `A1200 style' and `A4000 style' of the Gayle IDE interface, both the `A1200 style' and `A4000 style' of the Gayle IDE interface,
...@@ -951,9 +960,8 @@ config BLK_DEV_IDEDOUBLER ...@@ -951,9 +960,8 @@ config BLK_DEV_IDEDOUBLER
runtime using the "ide=doubler" kernel boot parameter. runtime using the "ide=doubler" kernel boot parameter.
config BLK_DEV_BUDDHA config BLK_DEV_BUDDHA
bool "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)" tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
depends on ZORRO && EXPERIMENTAL depends on ZORRO && EXPERIMENTAL
select IDE_GENERIC
help help
This is the IDE driver for the IDE interfaces on the Buddha, This is the IDE driver for the IDE interfaces on the Buddha,
Catweasel and X-Surf expansion boards. It supports up to two interfaces Catweasel and X-Surf expansion boards. It supports up to two interfaces
...@@ -964,9 +972,8 @@ config BLK_DEV_BUDDHA ...@@ -964,9 +972,8 @@ config BLK_DEV_BUDDHA
to one of its IDE interfaces. to one of its IDE interfaces.
config BLK_DEV_FALCON_IDE config BLK_DEV_FALCON_IDE
bool "Falcon IDE interface support" tristate "Falcon IDE interface support"
depends on ATARI depends on ATARI
select IDE_GENERIC
help help
This is the IDE driver for the builtin IDE interface on the Atari This is the IDE driver for the builtin IDE interface on the Atari
Falcon. Say Y if you have a Falcon and want to use IDE devices (hard Falcon. Say Y if you have a Falcon and want to use IDE devices (hard
...@@ -974,9 +981,8 @@ config BLK_DEV_FALCON_IDE ...@@ -974,9 +981,8 @@ config BLK_DEV_FALCON_IDE
interface. interface.
config BLK_DEV_MAC_IDE config BLK_DEV_MAC_IDE
bool "Macintosh Quadra/Powerbook IDE interface support" tristate "Macintosh Quadra/Powerbook IDE interface support"
depends on MAC depends on MAC
select IDE_GENERIC
help help
This is the IDE driver for the builtin IDE interface on some m68k This is the IDE driver for the builtin IDE interface on some m68k
Macintosh models. It supports both the `Quadra style' (used in Macintosh models. It supports both the `Quadra style' (used in
...@@ -988,18 +994,16 @@ config BLK_DEV_MAC_IDE ...@@ -988,18 +994,16 @@ config BLK_DEV_MAC_IDE
builtin IDE interface. builtin IDE interface.
config BLK_DEV_Q40IDE config BLK_DEV_Q40IDE
bool "Q40/Q60 IDE interface support" tristate "Q40/Q60 IDE interface support"
depends on Q40 depends on Q40
select IDE_GENERIC
help help
Enable the on-board IDE controller in the Q40/Q60. This should Enable the on-board IDE controller in the Q40/Q60. This should
normally be on; disable it only if you are running a custom hard normally be on; disable it only if you are running a custom hard
drive subsystem through an expansion card. drive subsystem through an expansion card.
config BLK_DEV_MPC8xx_IDE config BLK_DEV_MPC8xx_IDE
bool "MPC8xx IDE support" tristate "MPC8xx IDE support"
depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE
select IDE_GENERIC
help help
This option provides support for IDE on Motorola MPC8xx Systems. This option provides support for IDE on Motorola MPC8xx Systems.
Please see 'Type of MPC8xx IDE interface' for details. Please see 'Type of MPC8xx IDE interface' for details.
......
...@@ -7,41 +7,37 @@ ...@@ -7,41 +7,37 @@
# Note : at this point, these files are compiled on all systems. # Note : at this point, these files are compiled on all systems.
# In the future, some of these should be built conditionally. # In the future, some of these should be built conditionally.
# #
# First come modules that register themselves with the core # link order is important here
EXTRA_CFLAGS += -Idrivers/ide EXTRA_CFLAGS += -Idrivers/ide
obj-$(CONFIG_BLK_DEV_IDE) += pci/
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-core-$(CONFIG_BLK_DEV_CMD640) += pci/cmd640.o # core IDE code
# Core IDE code - must come before legacy
ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o
ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o
ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o
ide-core-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o
# built-in only drivers from arm/ obj-$(CONFIG_BLK_DEV_IDE) += ide-core.o
ide-core-$(CONFIG_IDE_ARM) += arm/ide_arm.o
# built-in only drivers from legacy/ ifeq ($(CONFIG_IDE_ARM), y)
ide-core-$(CONFIG_BLK_DEV_BUDDHA) += legacy/buddha.o ide-arm-core-y += arm/ide_arm.o
ide-core-$(CONFIG_BLK_DEV_FALCON_IDE) += legacy/falconide.o obj-y += ide-arm-core.o
ide-core-$(CONFIG_BLK_DEV_GAYLE) += legacy/gayle.o endif
ide-core-$(CONFIG_BLK_DEV_MAC_IDE) += legacy/macide.o
ide-core-$(CONFIG_BLK_DEV_Q40IDE) += legacy/q40ide.o
# built-in only drivers from ppc/ obj-$(CONFIG_BLK_DEV_IDE) += legacy/ pci/
ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ppc/mpc8xx.o
ide-core-$(CONFIG_BLK_DEV_IDE_PMAC) += ppc/pmac.o
# built-in only drivers from h8300/ obj-$(CONFIG_IDEPCI_PCIBUS_ORDER) += ide-scan-pci.o
ide-core-$(CONFIG_IDE_H8300) += h8300/ide-h8300.o
obj-$(CONFIG_BLK_DEV_IDE) += ide-core.o ifeq ($(CONFIG_BLK_DEV_CMD640), y)
cmd640-core-y += pci/cmd640.o
obj-y += cmd640-core.o
endif
obj-$(CONFIG_BLK_DEV_IDE) += cris/ ppc/
obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
obj-$(CONFIG_IDE_H8300) += h8300/
obj-$(CONFIG_IDE_GENERIC) += ide-generic.o obj-$(CONFIG_IDE_GENERIC) += ide-generic.o
obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o
...@@ -49,6 +45,20 @@ obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o ...@@ -49,6 +45,20 @@ obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o
obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o
obj-$(CONFIG_BLK_DEV_IDE) += legacy/ arm/ mips/ ifeq ($(CONFIG_BLK_DEV_IDECS), y)
obj-$(CONFIG_BLK_DEV_HD) += legacy/ ide-cs-core-y += legacy/ide-cs.o
obj-$(CONFIG_ETRAX_IDE) += cris/ obj-y += ide-cs-core.o
endif
ifeq ($(CONFIG_BLK_DEV_PLATFORM), y)
ide-platform-core-y += legacy/ide_platform.o
obj-y += ide-platform-core.o
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
...@@ -3,4 +3,8 @@ obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o ...@@ -3,4 +3,8 @@ obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o
obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o
obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o
ifeq ($(CONFIG_IDE_ARM), m)
obj-m += ide_arm.o
endif
EXTRA_CFLAGS := -Idrivers/ide EXTRA_CFLAGS := -Idrivers/ide
...@@ -45,7 +45,7 @@ bastide_register(unsigned int base, unsigned int aux, int irq, ...@@ -45,7 +45,7 @@ bastide_register(unsigned int base, unsigned int aux, int irq,
hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20); hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20);
hw.irq = irq; hw.irq = irq;
ide_register_hw(&hw, NULL, 0, hwif); ide_register_hw(&hw, NULL, hwif);
return 0; return 0;
} }
......
...@@ -287,26 +287,10 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode) ...@@ -287,26 +287,10 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data); ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
} }
static void icside_dma_host_off(ide_drive_t *drive) static void icside_dma_host_set(ide_drive_t *drive, int on)
{ {
} }
static void icside_dma_off_quietly(ide_drive_t *drive)
{
drive->using_dma = 0;
}
static void icside_dma_host_on(ide_drive_t *drive)
{
}
static int icside_dma_on(ide_drive_t *drive)
{
drive->using_dma = 1;
return 0;
}
static int icside_dma_end(ide_drive_t *drive) static int icside_dma_end(ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
...@@ -422,10 +406,7 @@ static void icside_dma_init(ide_hwif_t *hwif) ...@@ -422,10 +406,7 @@ static void icside_dma_init(ide_hwif_t *hwif)
hwif->dmatable_dma = 0; hwif->dmatable_dma = 0;
hwif->set_dma_mode = icside_set_dma_mode; hwif->set_dma_mode = icside_set_dma_mode;
hwif->dma_host_off = icside_dma_host_off; hwif->dma_host_set = icside_dma_host_set;
hwif->dma_off_quietly = icside_dma_off_quietly;
hwif->dma_host_on = icside_dma_host_on;
hwif->ide_dma_on = icside_dma_on;
hwif->dma_setup = icside_dma_setup; hwif->dma_setup = icside_dma_setup;
hwif->dma_exec_cmd = icside_dma_exec_cmd; hwif->dma_exec_cmd = icside_dma_exec_cmd;
hwif->dma_start = icside_dma_start; hwif->dma_start = icside_dma_start;
......
...@@ -24,12 +24,25 @@ ...@@ -24,12 +24,25 @@
# define IDE_ARM_IRQ IRQ_HARDDISK # define IDE_ARM_IRQ IRQ_HARDDISK
#endif #endif
void __init ide_arm_init(void) static int __init ide_arm_init(void)
{ {
ide_hwif_t *hwif;
hw_regs_t hw; hw_regs_t hw;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
memset(&hw, 0, sizeof(hw)); memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206); ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206);
hw.irq = IDE_ARM_IRQ; hw.irq = IDE_ARM_IRQ;
ide_register_hw(&hw, NULL, 1, NULL);
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (hwif) {
ide_init_port_hw(hwif, &hw);
idx[0] = hwif->index;
ide_device_add(idx);
}
return 0;
} }
module_init(ide_arm_init);
...@@ -13,26 +13,18 @@ ...@@ -13,26 +13,18 @@
#include <asm/ecard.h> #include <asm/ecard.h>
static ide_hwif_t * static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base,
rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int irq) void __iomem *ctrl, unsigned int sz, int irq)
{ {
unsigned long port = (unsigned long)base; unsigned long port = (unsigned long)base;
ide_hwif_t *hwif = ide_find_port(port);
int i; int i;
if (hwif == NULL)
goto out;
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
hwif->io_ports[i] = port; hw->io_ports[i] = port;
port += sz; port += sz;
} }
hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
hwif->irq = irq; hw->irq = irq;
hwif->mmio = 1;
default_hwif_mmiops(hwif);
out:
return hwif;
} }
static int __devinit static int __devinit
...@@ -42,6 +34,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -42,6 +34,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
void __iomem *base; void __iomem *base;
int ret; int ret;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
hw_regs_t hw;
ret = ecard_request_resources(ec); ret = ecard_request_resources(ec);
if (ret) if (ret)
...@@ -53,11 +46,17 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -53,11 +46,17 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
goto release; goto release;
} }
hwif = rapide_locate_hwif(base, base + 0x818, 1 << 6, ec->irq); hwif = ide_find_port((unsigned long)base);
if (hwif) { if (hwif) {
hwif->hwif_data = base; memset(&hw, 0, sizeof(hw));
hwif->gendev.parent = &ec->dev; rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq);
hwif->noprobe = 0; hw.chipset = ide_generic;
hw.dev = &ec->dev;
ide_init_port_hw(hwif, &hw);
hwif->mmio = 1;
default_hwif_mmiops(hwif);
idx[0] = hwif->index; idx[0] = hwif->index;
......
EXTRA_CFLAGS += -Idrivers/ide EXTRA_CFLAGS += -Idrivers/ide
obj-y += ide-cris.o obj-$(CONFIG_IDE_ETRAX) += ide-cris.o
...@@ -673,9 +673,8 @@ static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int); ...@@ -673,9 +673,8 @@ static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int);
static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int); static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int);
static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int); static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int); static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
static int cris_dma_on (ide_drive_t *drive);
static void cris_dma_off(ide_drive_t *drive) static void cris_dma_host_set(ide_drive_t *drive, int on)
{ {
} }
...@@ -755,13 +754,11 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed) ...@@ -755,13 +754,11 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed)
cris_ide_set_speed(TYPE_DMA, 0, strobe, hold); cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
} }
void __init static int __init init_e100_ide(void)
init_e100_ide (void)
{ {
hw_regs_t hw; hw_regs_t hw;
int ide_offsets[IDE_NR_PORTS]; int ide_offsets[IDE_NR_PORTS], h, i;
int h; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
int i;
printk("ide: ETRAX FS built-in ATA DMA controller\n"); printk("ide: ETRAX FS built-in ATA DMA controller\n");
...@@ -778,9 +775,11 @@ init_e100_ide (void) ...@@ -778,9 +775,11 @@ init_e100_ide (void)
ide_offsets, ide_offsets,
0, 0, cris_ide_ack_intr, 0, 0, cris_ide_ack_intr,
ide_default_irq(0)); ide_default_irq(0));
ide_register_hw(&hw, NULL, 1, &hwif); hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (hwif == NULL) if (hwif == NULL)
continue; continue;
ide_init_port_data(hwif, hwif->index);
ide_init_port_hw(hwif, &hw);
hwif->mmio = 1; hwif->mmio = 1;
hwif->chipset = ide_etrax100; hwif->chipset = ide_etrax100;
hwif->set_pio_mode = &cris_set_pio_mode; hwif->set_pio_mode = &cris_set_pio_mode;
...@@ -789,6 +788,7 @@ init_e100_ide (void) ...@@ -789,6 +788,7 @@ init_e100_ide (void)
hwif->ata_output_data = &cris_ide_output_data; hwif->ata_output_data = &cris_ide_output_data;
hwif->atapi_input_bytes = &cris_atapi_input_bytes; hwif->atapi_input_bytes = &cris_atapi_input_bytes;
hwif->atapi_output_bytes = &cris_atapi_output_bytes; hwif->atapi_output_bytes = &cris_atapi_output_bytes;
hwif->dma_host_set = &cris_dma_host_set;
hwif->ide_dma_end = &cris_dma_end; hwif->ide_dma_end = &cris_dma_end;
hwif->dma_setup = &cris_dma_setup; hwif->dma_setup = &cris_dma_setup;
hwif->dma_exec_cmd = &cris_dma_exec_cmd; hwif->dma_exec_cmd = &cris_dma_exec_cmd;
...@@ -799,9 +799,6 @@ init_e100_ide (void) ...@@ -799,9 +799,6 @@ init_e100_ide (void)
hwif->OUTBSYNC = &cris_ide_outbsync; hwif->OUTBSYNC = &cris_ide_outbsync;
hwif->INB = &cris_ide_inb; hwif->INB = &cris_ide_inb;
hwif->INW = &cris_ide_inw; hwif->INW = &cris_ide_inw;
hwif->dma_host_off = &cris_dma_off;
hwif->dma_host_on = &cris_dma_on;
hwif->dma_off_quietly = &cris_dma_off;
hwif->cbl = ATA_CBL_PATA40; hwif->cbl = ATA_CBL_PATA40;
hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA; hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
hwif->pio_mask = ATA_PIO4, hwif->pio_mask = ATA_PIO4,
...@@ -809,6 +806,8 @@ init_e100_ide (void) ...@@ -809,6 +806,8 @@ init_e100_ide (void)
hwif->drives[1].autotune = 1; hwif->drives[1].autotune = 1;
hwif->ultra_mask = cris_ultra_mask; hwif->ultra_mask = cris_ultra_mask;
hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */ hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
idx[h] = hwif->index;
} }
/* Reset pulse */ /* Reset pulse */
...@@ -821,14 +820,12 @@ init_e100_ide (void) ...@@ -821,14 +820,12 @@ init_e100_ide (void)
cris_ide_set_speed(TYPE_PIO, ATA_PIO4_SETUP, ATA_PIO4_STROBE, ATA_PIO4_HOLD); cris_ide_set_speed(TYPE_PIO, ATA_PIO4_SETUP, ATA_PIO4_STROBE, ATA_PIO4_HOLD);
cris_ide_set_speed(TYPE_DMA, 0, ATA_DMA2_STROBE, ATA_DMA2_HOLD); cris_ide_set_speed(TYPE_DMA, 0, ATA_DMA2_STROBE, ATA_DMA2_HOLD);
cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0); cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0);
}
static int cris_dma_on (ide_drive_t *drive) ide_device_add(idx);
{
return 0; return 0;
} }
static cris_dma_descr_type mydescr __attribute__ ((__aligned__(16))); static cris_dma_descr_type mydescr __attribute__ ((__aligned__(16)));
/* /*
...@@ -1060,3 +1057,5 @@ static void cris_dma_start(ide_drive_t *drive) ...@@ -1060,3 +1057,5 @@ static void cris_dma_start(ide_drive_t *drive)
LED_DISK_READ(1); LED_DISK_READ(1);
} }
} }
module_init(init_e100_ide);
obj-$(CONFIG_IDE_H8300) += ide-h8300.o
...@@ -84,11 +84,12 @@ static inline void hwif_setup(ide_hwif_t *hwif) ...@@ -84,11 +84,12 @@ static inline void hwif_setup(ide_hwif_t *hwif)
hwif->INSL = NULL; hwif->INSL = NULL;
} }
void __init h8300_ide_init(void) static int __init h8300_ide_init(void)
{ {
hw_regs_t hw; hw_regs_t hw;
ide_hwif_t *hwif; ide_hwif_t *hwif;
int idx; int index;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300")) if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300"))
goto out_busy; goto out_busy;
...@@ -100,16 +101,28 @@ void __init h8300_ide_init(void) ...@@ -100,16 +101,28 @@ void __init h8300_ide_init(void)
hw_setup(&hw); hw_setup(&hw);
/* register if */ /* register if */
idx = ide_register_hw(&hw, NULL, 1, &hwif); hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (idx == -1) { if (hwif == NULL) {
printk(KERN_ERR "ide-h8300: IDE I/F register failed\n"); printk(KERN_ERR "ide-h8300: IDE I/F register failed\n");
return; return -ENOENT;
} }
index = hwif->index;
ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
hwif_setup(hwif); hwif_setup(hwif);
printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", idx); printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", index);
return;
idx[0] = index;
ide_device_add(idx);
return 0;
out_busy: out_busy:
printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n"); printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n");
return -EBUSY;
} }
module_init(h8300_ide_init);
...@@ -386,7 +386,7 @@ static int taskfile_load_raw(ide_drive_t *drive, ...@@ -386,7 +386,7 @@ static int taskfile_load_raw(ide_drive_t *drive,
/* convert gtf to IDE Taskfile */ /* convert gtf to IDE Taskfile */
memcpy(&args.tf_array[7], &gtf->tfa, 7); memcpy(&args.tf_array[7], &gtf->tfa, 7);
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (ide_noacpitfs) { if (ide_noacpitfs) {
DEBPRINT("_GTF execution disabled\n"); DEBPRINT("_GTF execution disabled\n");
......
...@@ -201,7 +201,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, ...@@ -201,7 +201,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
memset(&task, 0, sizeof(task)); memset(&task, 0, sizeof(task));
task.tf_flags = IDE_TFLAG_NO_SELECT_MASK; /* FIXME? */ task.tf_flags = IDE_TFLAG_NO_SELECT_MASK; /* FIXME? */
task.tf_flags |= (IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE); task.tf_flags |= (IDE_TFLAG_TF | IDE_TFLAG_DEVICE);
if (drive->select.b.lba) { if (drive->select.b.lba) {
if (lba48) { if (lba48) {
...@@ -219,13 +219,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, ...@@ -219,13 +219,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
tf->lbal = (u8) block; tf->lbal = (u8) block;
tf->lbam = (u8)(block >> 8); tf->lbam = (u8)(block >> 8);
tf->lbah = (u8)(block >> 16); tf->lbah = (u8)(block >> 16);
#ifdef DEBUG
printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n", task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
drive->name, tf->hob_nsect, tf->nsect,
tf->hob_lbah, tf->hob_lbam, tf->hob_lbal,
tf->lbah, tf->lbam, tf->lbal);
#endif
task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB);
} else { } else {
tf->nsect = nsectors & 0xff; tf->nsect = nsectors & 0xff;
tf->lbal = block; tf->lbal = block;
...@@ -319,9 +314,9 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48) ...@@ -319,9 +314,9 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
else else
tf->command = WIN_READ_NATIVE_MAX; tf->command = WIN_READ_NATIVE_MAX;
tf->device = ATA_LBA; tf->device = ATA_LBA;
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (lba48) if (lba48)
args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB); args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
/* submit command request */ /* submit command request */
ide_no_data_taskfile(drive, &args); ide_no_data_taskfile(drive, &args);
...@@ -358,9 +353,9 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) ...@@ -358,9 +353,9 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
tf->command = WIN_SET_MAX; tf->command = WIN_SET_MAX;
} }
tf->device |= ATA_LBA; tf->device |= ATA_LBA;
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (lba48) if (lba48)
args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB); args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
/* submit command request */ /* submit command request */
ide_no_data_taskfile(drive, &args); ide_no_data_taskfile(drive, &args);
/* if OK, compute maximum address value */ /* if OK, compute maximum address value */
...@@ -500,7 +495,7 @@ static int smart_enable(ide_drive_t *drive) ...@@ -500,7 +495,7 @@ static int smart_enable(ide_drive_t *drive)
tf->lbam = SMART_LCYL_PASS; tf->lbam = SMART_LCYL_PASS;
tf->lbah = SMART_HCYL_PASS; tf->lbah = SMART_HCYL_PASS;
tf->command = WIN_SMART; tf->command = WIN_SMART;
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
return ide_no_data_taskfile(drive, &args); return ide_no_data_taskfile(drive, &args);
} }
...@@ -515,7 +510,7 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) ...@@ -515,7 +510,7 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
tf->lbam = SMART_LCYL_PASS; tf->lbam = SMART_LCYL_PASS;
tf->lbah = SMART_HCYL_PASS; tf->lbah = SMART_HCYL_PASS;
tf->command = WIN_SMART; tf->command = WIN_SMART;
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
args.data_phase = TASKFILE_IN; args.data_phase = TASKFILE_IN;
(void) smart_enable(drive); (void) smart_enable(drive);
return ide_raw_taskfile(drive, &args, buf, 1); return ide_raw_taskfile(drive, &args, buf, 1);
...@@ -625,8 +620,10 @@ static int set_multcount(ide_drive_t *drive, int arg) ...@@ -625,8 +620,10 @@ static int set_multcount(ide_drive_t *drive, int arg)
if (drive->special.b.set_multmode) if (drive->special.b.set_multmode)
return -EBUSY; return -EBUSY;
ide_init_drive_cmd (&rq); ide_init_drive_cmd (&rq);
rq.cmd_type = REQ_TYPE_ATA_CMD; rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
drive->mult_req = arg; drive->mult_req = arg;
drive->special.b.set_multmode = 1; drive->special.b.set_multmode = 1;
(void) ide_do_drive_cmd (drive, &rq, ide_wait); (void) ide_do_drive_cmd (drive, &rq, ide_wait);
...@@ -694,7 +691,7 @@ static int write_cache(ide_drive_t *drive, int arg) ...@@ -694,7 +691,7 @@ static int write_cache(ide_drive_t *drive, int arg)
args.tf.feature = arg ? args.tf.feature = arg ?
SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
args.tf.command = WIN_SETFEATURES; args.tf.command = WIN_SETFEATURES;
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
err = ide_no_data_taskfile(drive, &args); err = ide_no_data_taskfile(drive, &args);
if (err == 0) if (err == 0)
drive->wcache = arg; drive->wcache = arg;
...@@ -714,7 +711,7 @@ static int do_idedisk_flushcache (ide_drive_t *drive) ...@@ -714,7 +711,7 @@ static int do_idedisk_flushcache (ide_drive_t *drive)
args.tf.command = WIN_FLUSH_CACHE_EXT; args.tf.command = WIN_FLUSH_CACHE_EXT;
else else
args.tf.command = WIN_FLUSH_CACHE; args.tf.command = WIN_FLUSH_CACHE;
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
return ide_no_data_taskfile(drive, &args); return ide_no_data_taskfile(drive, &args);
} }
...@@ -729,7 +726,7 @@ static int set_acoustic (ide_drive_t *drive, int arg) ...@@ -729,7 +726,7 @@ static int set_acoustic (ide_drive_t *drive, int arg)
args.tf.feature = arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM; args.tf.feature = arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM;
args.tf.nsect = arg; args.tf.nsect = arg;
args.tf.command = WIN_SETFEATURES; args.tf.command = WIN_SETFEATURES;
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
ide_no_data_taskfile(drive, &args); ide_no_data_taskfile(drive, &args);
drive->acoustic = arg; drive->acoustic = arg;
return 0; return 0;
...@@ -766,7 +763,6 @@ static void idedisk_add_settings(ide_drive_t *drive) ...@@ -766,7 +763,6 @@ static void idedisk_add_settings(ide_drive_t *drive)
ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL);
ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL);
ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1, &drive->addressing, set_lba_addressing); ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1, &drive->addressing, set_lba_addressing);
ide_add_setting(drive, "bswap", SETTING_READ, TYPE_BYTE, 0, 1, 1, 1, &drive->bswap, NULL);
ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0, id->max_multsect, 1, 1, &drive->mult_count, set_multcount); ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0, id->max_multsect, 1, 1, &drive->mult_count, set_multcount);
ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr); ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr);
ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL); ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL);
...@@ -975,6 +971,17 @@ static ide_driver_t idedisk_driver = { ...@@ -975,6 +971,17 @@ static ide_driver_t idedisk_driver = {
#endif #endif
}; };
static int idedisk_set_doorlock(ide_drive_t *drive, int on)
{
ide_task_t task;
memset(&task, 0, sizeof(task));
task.tf.command = on ? WIN_DOORLOCK : WIN_DOORUNLOCK;
task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
return ide_no_data_taskfile(drive, &task);
}
static int idedisk_open(struct inode *inode, struct file *filp) static int idedisk_open(struct inode *inode, struct file *filp)
{ {
struct gendisk *disk = inode->i_bdev->bd_disk; struct gendisk *disk = inode->i_bdev->bd_disk;
...@@ -989,17 +996,13 @@ static int idedisk_open(struct inode *inode, struct file *filp) ...@@ -989,17 +996,13 @@ static int idedisk_open(struct inode *inode, struct file *filp)
idkp->openers++; idkp->openers++;
if (drive->removable && idkp->openers == 1) { if (drive->removable && idkp->openers == 1) {
ide_task_t args;
memset(&args, 0, sizeof(ide_task_t));
args.tf.command = WIN_DOORLOCK;
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
check_disk_change(inode->i_bdev); check_disk_change(inode->i_bdev);
/* /*
* Ignore the return code from door_lock, * Ignore the return code from door_lock,
* since the open() has already succeeded, * since the open() has already succeeded,
* and the door_lock is irrelevant at this point. * and the door_lock is irrelevant at this point.
*/ */
if (drive->doorlocking && ide_no_data_taskfile(drive, &args)) if (drive->doorlocking && idedisk_set_doorlock(drive, 1))
drive->doorlocking = 0; drive->doorlocking = 0;
} }
return 0; return 0;
...@@ -1015,11 +1018,7 @@ static int idedisk_release(struct inode *inode, struct file *filp) ...@@ -1015,11 +1018,7 @@ static int idedisk_release(struct inode *inode, struct file *filp)
ide_cacheflush_p(drive); ide_cacheflush_p(drive);
if (drive->removable && idkp->openers == 1) { if (drive->removable && idkp->openers == 1) {
ide_task_t args; if (drive->doorlocking && idedisk_set_doorlock(drive, 0))
memset(&args, 0, sizeof(ide_task_t));
args.tf.command = WIN_DOORUNLOCK;
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
if (drive->doorlocking && ide_no_data_taskfile(drive, &args))
drive->doorlocking = 0; drive->doorlocking = 0;
} }
......
...@@ -153,13 +153,7 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive) ...@@ -153,13 +153,7 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
if (!dma_stat) { if (!dma_stat) {
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
if (rq->rq_disk) { task_end_request(drive, rq, stat);
ide_driver_t *drv;
drv = *(ide_driver_t **)rq->rq_disk->private_data;
drv->end_request(drive, 1, rq->nr_sectors);
} else
ide_end_request(drive, 1, rq->nr_sectors);
return ide_stopped; return ide_stopped;
} }
printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
...@@ -408,23 +402,29 @@ static int dma_timer_expiry (ide_drive_t *drive) ...@@ -408,23 +402,29 @@ static int dma_timer_expiry (ide_drive_t *drive)
} }
/** /**
* ide_dma_host_off - Generic DMA kill * ide_dma_host_set - Enable/disable DMA on a host
* @drive: drive to control * @drive: drive to control
* *
* Perform the generic IDE controller DMA off operation. This * Enable/disable DMA on an IDE controller following generic
* works for most IDE bus mastering controllers * bus-mastering IDE controller behaviour.
*/ */
void ide_dma_host_off(ide_drive_t *drive) void ide_dma_host_set(ide_drive_t *drive, int on)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
u8 unit = (drive->select.b.unit & 0x01); u8 unit = (drive->select.b.unit & 0x01);
u8 dma_stat = hwif->INB(hwif->dma_status); u8 dma_stat = hwif->INB(hwif->dma_status);
hwif->OUTB((dma_stat & ~(1<<(5+unit))), hwif->dma_status); if (on)
dma_stat |= (1 << (5 + unit));
else
dma_stat &= ~(1 << (5 + unit));
hwif->OUTB(dma_stat, hwif->dma_status);
} }
EXPORT_SYMBOL(ide_dma_host_off); EXPORT_SYMBOL_GPL(ide_dma_host_set);
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
/** /**
* ide_dma_off_quietly - Generic DMA kill * ide_dma_off_quietly - Generic DMA kill
...@@ -438,11 +438,10 @@ void ide_dma_off_quietly(ide_drive_t *drive) ...@@ -438,11 +438,10 @@ void ide_dma_off_quietly(ide_drive_t *drive)
drive->using_dma = 0; drive->using_dma = 0;
ide_toggle_bounce(drive, 0); ide_toggle_bounce(drive, 0);
drive->hwif->dma_host_off(drive); drive->hwif->dma_host_set(drive, 0);
} }
EXPORT_SYMBOL(ide_dma_off_quietly); EXPORT_SYMBOL(ide_dma_off_quietly);
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
/** /**
* ide_dma_off - disable DMA on a device * ide_dma_off - disable DMA on a device
...@@ -455,52 +454,29 @@ EXPORT_SYMBOL(ide_dma_off_quietly); ...@@ -455,52 +454,29 @@ EXPORT_SYMBOL(ide_dma_off_quietly);
void ide_dma_off(ide_drive_t *drive) void ide_dma_off(ide_drive_t *drive)
{ {
printk(KERN_INFO "%s: DMA disabled\n", drive->name); printk(KERN_INFO "%s: DMA disabled\n", drive->name);
drive->hwif->dma_off_quietly(drive); ide_dma_off_quietly(drive);
} }
EXPORT_SYMBOL(ide_dma_off); EXPORT_SYMBOL(ide_dma_off);
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
/**
* ide_dma_host_on - Enable DMA on a host
* @drive: drive to enable for DMA
*
* Enable DMA on an IDE controller following generic bus mastering
* IDE controller behaviour
*/
void ide_dma_host_on(ide_drive_t *drive)
{
if (drive->using_dma) {
ide_hwif_t *hwif = HWIF(drive);
u8 unit = (drive->select.b.unit & 0x01);
u8 dma_stat = hwif->INB(hwif->dma_status);
hwif->OUTB((dma_stat|(1<<(5+unit))), hwif->dma_status);
}
}
EXPORT_SYMBOL(ide_dma_host_on);
/** /**
* __ide_dma_on - Enable DMA on a device * ide_dma_on - Enable DMA on a device
* @drive: drive to enable DMA on * @drive: drive to enable DMA on
* *
* Enable IDE DMA for a device on this IDE controller. * Enable IDE DMA for a device on this IDE controller.
*/ */
int __ide_dma_on (ide_drive_t *drive) void ide_dma_on(ide_drive_t *drive)
{ {
drive->using_dma = 1; drive->using_dma = 1;
ide_toggle_bounce(drive, 1); ide_toggle_bounce(drive, 1);
drive->hwif->dma_host_on(drive); drive->hwif->dma_host_set(drive, 1);
return 0;
} }
EXPORT_SYMBOL(__ide_dma_on); EXPORT_SYMBOL(ide_dma_on);
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
/** /**
* ide_dma_setup - begin a DMA phase * ide_dma_setup - begin a DMA phase
* @drive: target device * @drive: target device
...@@ -755,6 +731,7 @@ EXPORT_SYMBOL_GPL(ide_find_dma_mode); ...@@ -755,6 +731,7 @@ EXPORT_SYMBOL_GPL(ide_find_dma_mode);
static int ide_tune_dma(ide_drive_t *drive) static int ide_tune_dma(ide_drive_t *drive)
{ {
ide_hwif_t *hwif = drive->hwif;
u8 speed; u8 speed;
if (noautodma || drive->nodma || (drive->id->capability & 1) == 0) if (noautodma || drive->nodma || (drive->id->capability & 1) == 0)
...@@ -767,15 +744,21 @@ static int ide_tune_dma(ide_drive_t *drive) ...@@ -767,15 +744,21 @@ static int ide_tune_dma(ide_drive_t *drive)
if (ide_id_dma_bug(drive)) if (ide_id_dma_bug(drive))
return 0; return 0;
if (drive->hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA) if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
return config_drive_for_dma(drive); return config_drive_for_dma(drive);
speed = ide_max_dma_mode(drive); speed = ide_max_dma_mode(drive);
if (!speed) if (!speed) {
return 0; /* is this really correct/needed? */
if ((hwif->host_flags & IDE_HFLAG_CY82C693) &&
ide_dma_good_drive(drive))
return 1;
else
return 0;
}
if (drive->hwif->host_flags & IDE_HFLAG_NO_SET_MODE) if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
return 0; return 0;
if (ide_set_dma_mode(drive, speed)) if (ide_set_dma_mode(drive, speed))
...@@ -820,7 +803,6 @@ int ide_id_dma_bug(ide_drive_t *drive) ...@@ -820,7 +803,6 @@ int ide_id_dma_bug(ide_drive_t *drive)
int ide_set_dma(ide_drive_t *drive) int ide_set_dma(ide_drive_t *drive)
{ {
ide_hwif_t *hwif = drive->hwif;
int rc; int rc;
/* /*
...@@ -829,13 +811,15 @@ int ide_set_dma(ide_drive_t *drive) ...@@ -829,13 +811,15 @@ int ide_set_dma(ide_drive_t *drive)
* things, if not checked and cleared. * things, if not checked and cleared.
* PARANOIA!!! * PARANOIA!!!
*/ */
hwif->dma_off_quietly(drive); ide_dma_off_quietly(drive);
rc = ide_dma_check(drive); rc = ide_dma_check(drive);
if (rc) if (rc)
return rc; return rc;
return hwif->ide_dma_on(drive); ide_dma_on(drive);
return 0;
} }
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
...@@ -972,14 +956,8 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports) ...@@ -972,14 +956,8 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports)
if (!(hwif->dma_prdtable)) if (!(hwif->dma_prdtable))
hwif->dma_prdtable = (hwif->dma_base + 4); hwif->dma_prdtable = (hwif->dma_base + 4);
if (!hwif->dma_off_quietly) if (!hwif->dma_host_set)
hwif->dma_off_quietly = &ide_dma_off_quietly; hwif->dma_host_set = &ide_dma_host_set;
if (!hwif->dma_host_off)
hwif->dma_host_off = &ide_dma_host_off;
if (!hwif->ide_dma_on)
hwif->ide_dma_on = &__ide_dma_on;
if (!hwif->dma_host_on)
hwif->dma_host_on = &ide_dma_host_on;
if (!hwif->dma_setup) if (!hwif->dma_setup)
hwif->dma_setup = &ide_dma_setup; hwif->dma_setup = &ide_dma_setup;
if (!hwif->dma_exec_cmd) if (!hwif->dma_exec_cmd)
......
...@@ -14,10 +14,16 @@ ...@@ -14,10 +14,16 @@
static int __init ide_generic_init(void) static int __init ide_generic_init(void)
{ {
u8 idx[MAX_HWIFS];
int i;
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
ide_get_lock(NULL, NULL); /* for atari only */ ide_get_lock(NULL, NULL); /* for atari only */
(void)ideprobe_init(); for (i = 0; i < MAX_HWIFS; i++)
idx[i] = ide_hwifs[i].present ? 0xff : i;
ide_device_add_all(idx);
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
ide_release_lock(); /* for atari only */ ide_release_lock(); /* for atari only */
......
...@@ -75,7 +75,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, ...@@ -75,7 +75,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
*/ */
if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
drive->state = 0; drive->state = 0;
HWGROUP(drive)->hwif->ide_dma_on(drive); ide_dma_on(drive);
} }
if (!end_that_request_chunk(rq, uptodate, nr_bytes)) { if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
...@@ -219,7 +219,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * ...@@ -219,7 +219,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
* we could be smarter and check for current xfer_speed * we could be smarter and check for current xfer_speed
* in struct drive etc... * in struct drive etc...
*/ */
if (drive->hwif->ide_dma_on == NULL) if (drive->hwif->dma_host_set == NULL)
break; break;
/* /*
* TODO: respect ->using_dma setting * TODO: respect ->using_dma setting
...@@ -231,7 +231,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * ...@@ -231,7 +231,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
return ide_stopped; return ide_stopped;
out_do_tf: out_do_tf:
args->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
args->data_phase = TASKFILE_NO_DATA; args->data_phase = TASKFILE_NO_DATA;
return do_rw_taskfile(drive, args); return do_rw_taskfile(drive, args);
} }
...@@ -354,7 +354,6 @@ void ide_tf_read(ide_drive_t *drive, ide_task_t *task) ...@@ -354,7 +354,6 @@ void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
{ {
ide_hwif_t *hwif = HWIF(drive);
unsigned long flags; unsigned long flags;
struct request *rq; struct request *rq;
...@@ -362,17 +361,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) ...@@ -362,17 +361,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
rq = HWGROUP(drive)->rq; rq = HWGROUP(drive)->rq;
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
if (rq->cmd_type == REQ_TYPE_ATA_CMD) { if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
u8 *args = (u8 *) rq->buffer;
if (rq->errors == 0)
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
if (args) {
args[0] = stat;
args[1] = err;
args[2] = hwif->INB(IDE_NSECTOR_REG);
}
} else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *args = (ide_task_t *) rq->special; ide_task_t *args = (ide_task_t *) rq->special;
if (rq->errors == 0) if (rq->errors == 0)
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
...@@ -383,10 +372,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) ...@@ -383,10 +372,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
tf->error = err; tf->error = err;
tf->status = stat; tf->status = stat;
args->tf_flags |= (IDE_TFLAG_IN_TF|IDE_TFLAG_IN_DEVICE);
if (args->tf_flags & IDE_TFLAG_LBA48)
args->tf_flags |= IDE_TFLAG_IN_HOB;
ide_tf_read(drive, args); ide_tf_read(drive, args);
} }
} else if (blk_pm_request(rq)) { } else if (blk_pm_request(rq)) {
...@@ -626,42 +611,6 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg) ...@@ -626,42 +611,6 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg)
return __ide_abort(drive, rq); return __ide_abort(drive, rq);
} }
/**
* drive_cmd_intr - drive command completion interrupt
* @drive: drive the completion interrupt occurred on
*
* drive_cmd_intr() is invoked on completion of a special DRIVE_CMD.
* We do any necessary data reading and then wait for the drive to
* go non busy. At that point we may read the error data and complete
* the request
*/
static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
ide_hwif_t *hwif = HWIF(drive);
u8 *args = (u8 *) rq->buffer;
u8 stat = hwif->INB(IDE_STATUS_REG);
int retries = 10;
local_irq_enable_in_hardirq();
if (rq->cmd_type == REQ_TYPE_ATA_CMD &&
(stat & DRQ_STAT) && args && args[3]) {
u8 io_32bit = drive->io_32bit;
drive->io_32bit = 0;
hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS);
drive->io_32bit = io_32bit;
while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
udelay(100);
}
if (!OK_STAT(stat, READY_STAT, BAD_STAT))
return ide_error(drive, "drive_cmd", stat);
/* calls ide_end_drive_cmd */
ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
return ide_stopped;
}
static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
{ {
tf->nsect = drive->sect; tf->nsect = drive->sect;
...@@ -710,7 +659,7 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) ...@@ -710,7 +659,7 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
return ide_stopped; return ide_stopped;
} }
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE |
IDE_TFLAG_CUSTOM_HANDLER; IDE_TFLAG_CUSTOM_HANDLER;
do_rw_taskfile(drive, &args); do_rw_taskfile(drive, &args);
...@@ -787,7 +736,7 @@ static ide_startstop_t do_special (ide_drive_t *drive) ...@@ -787,7 +736,7 @@ static ide_startstop_t do_special (ide_drive_t *drive)
if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
if (keep_dma) if (keep_dma)
hwif->ide_dma_on(drive); ide_dma_on(drive);
} }
} }
...@@ -847,16 +796,9 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, ...@@ -847,16 +796,9 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
struct request *rq) struct request *rq)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
u8 *args = rq->buffer; ide_task_t *task = rq->special;
ide_task_t ltask;
struct ide_taskfile *tf = &ltask.tf;
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *task = rq->special;
if (task == NULL)
goto done;
if (task) {
hwif->data_phase = task->data_phase; hwif->data_phase = task->data_phase;
switch (hwif->data_phase) { switch (hwif->data_phase) {
...@@ -873,33 +815,6 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, ...@@ -873,33 +815,6 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
return do_rw_taskfile(drive, task); return do_rw_taskfile(drive, task);
} }
if (args == NULL)
goto done;
memset(&ltask, 0, sizeof(ltask));
if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
#ifdef DEBUG
printk("%s: DRIVE_CMD\n", drive->name);
#endif
tf->feature = args[2];
if (args[0] == WIN_SMART) {
tf->nsect = args[3];
tf->lbal = args[1];
tf->lbam = 0x4f;
tf->lbah = 0xc2;
ltask.tf_flags = IDE_TFLAG_OUT_TF;
} else {
tf->nsect = args[1];
ltask.tf_flags = IDE_TFLAG_OUT_FEATURE |
IDE_TFLAG_OUT_NSECT;
}
}
tf->command = args[0];
ide_tf_load(drive, &ltask);
ide_execute_command(drive, args[0], &drive_cmd_intr, WAIT_WORSTCASE, NULL);
return ide_started;
done:
/* /*
* NULL is actually a valid way of waiting for * NULL is actually a valid way of waiting for
* all current requests to be flushed from the queue. * all current requests to be flushed from the queue.
...@@ -939,8 +854,7 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) ...@@ -939,8 +854,7 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
if (rc) if (rc)
printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
SELECT_DRIVE(drive); SELECT_DRIVE(drive);
if (IDE_CONTROL_REG) ide_set_irq(drive, 1);
HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
rc = ide_wait_not_busy(HWIF(drive), 100000); rc = ide_wait_not_busy(HWIF(drive), 100000);
if (rc) if (rc)
printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
...@@ -1004,8 +918,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) ...@@ -1004,8 +918,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
if (drive->current_speed == 0xff) if (drive->current_speed == 0xff)
ide_config_drive_speed(drive, drive->desired_speed); ide_config_drive_speed(drive, drive->desired_speed);
if (rq->cmd_type == REQ_TYPE_ATA_CMD || if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
return execute_drive_cmd(drive, rq); return execute_drive_cmd(drive, rq);
else if (blk_pm_request(rq)) { else if (blk_pm_request(rq)) {
struct request_pm_state *pm = rq->data; struct request_pm_state *pm = rq->data;
...@@ -1213,15 +1126,13 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) ...@@ -1213,15 +1126,13 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
} }
again: again:
hwif = HWIF(drive); hwif = HWIF(drive);
if (hwgroup->hwif->sharing_irq && if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif) {
hwif != hwgroup->hwif &&
hwif->io_ports[IDE_CONTROL_OFFSET]) {
/* /*
* set nIEN for previous hwif, drives in the * set nIEN for previous hwif, drives in the
* quirk_list may not like intr setups/cleanups * quirk_list may not like intr setups/cleanups
*/ */
if (drive->quirk_list != 1) if (drive->quirk_list != 1)
hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); ide_set_irq(drive, 0);
} }
hwgroup->hwif = hwif; hwgroup->hwif = hwif;
hwgroup->drive = drive; hwgroup->drive = drive;
...@@ -1334,7 +1245,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) ...@@ -1334,7 +1245,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
*/ */
drive->retry_pio++; drive->retry_pio++;
drive->state = DMA_PIO_RETRY; drive->state = DMA_PIO_RETRY;
hwif->dma_off_quietly(drive); ide_dma_off_quietly(drive);
/* /*
* un-busy drive etc (hwgroup->busy is cleared on return) and * un-busy drive etc (hwgroup->busy is cleared on return) and
...@@ -1679,7 +1590,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) ...@@ -1679,7 +1590,6 @@ irqreturn_t ide_intr (int irq, void *dev_id)
void ide_init_drive_cmd (struct request *rq) void ide_init_drive_cmd (struct request *rq)
{ {
memset(rq, 0, sizeof(*rq)); memset(rq, 0, sizeof(*rq));
rq->cmd_type = REQ_TYPE_ATA_CMD;
rq->ref_count = 1; rq->ref_count = 1;
} }
......
...@@ -619,7 +619,7 @@ u8 eighty_ninty_three (ide_drive_t *drive) ...@@ -619,7 +619,7 @@ u8 eighty_ninty_three (ide_drive_t *drive)
int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
{ {
if (args->tf.command == WIN_SETFEATURES && if (args->tf.command == WIN_SETFEATURES &&
args->tf.lbal > XFER_UDMA_2 && args->tf.nsect > XFER_UDMA_2 &&
args->tf.feature == SETFEATURES_XFER) { args->tf.feature == SETFEATURES_XFER) {
if (eighty_ninty_three(drive) == 0) { if (eighty_ninty_three(drive) == 0) {
printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
...@@ -639,7 +639,7 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) ...@@ -639,7 +639,7 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
int set_transfer (ide_drive_t *drive, ide_task_t *args) int set_transfer (ide_drive_t *drive, ide_task_t *args)
{ {
if (args->tf.command == WIN_SETFEATURES && if (args->tf.command == WIN_SETFEATURES &&
args->tf.lbal >= XFER_SW_DMA_0 && args->tf.nsect >= XFER_SW_DMA_0 &&
args->tf.feature == SETFEATURES_XFER && args->tf.feature == SETFEATURES_XFER &&
(drive->id->dma_ultra || (drive->id->dma_ultra ||
drive->id->dma_mword || drive->id->dma_mword ||
...@@ -688,8 +688,7 @@ int ide_driveid_update(ide_drive_t *drive) ...@@ -688,8 +688,7 @@ int ide_driveid_update(ide_drive_t *drive)
*/ */
SELECT_MASK(drive, 1); SELECT_MASK(drive, 1);
if (IDE_CONTROL_REG) ide_set_irq(drive, 1);
hwif->OUTB(drive->ctl,IDE_CONTROL_REG);
msleep(50); msleep(50);
hwif->OUTB(WIN_IDENTIFY, IDE_COMMAND_REG); hwif->OUTB(WIN_IDENTIFY, IDE_COMMAND_REG);
timeout = jiffies + WAIT_WORSTCASE; timeout = jiffies + WAIT_WORSTCASE;
...@@ -742,8 +741,8 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) ...@@ -742,8 +741,8 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
// msleep(50); // msleep(50);
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->ide_dma_on) /* check if host supports DMA */ if (hwif->dma_host_set) /* check if host supports DMA */
hwif->dma_host_off(drive); hwif->dma_host_set(drive, 0);
#endif #endif
/* Skip setting PIO flow-control modes on pre-EIDE drives */ /* Skip setting PIO flow-control modes on pre-EIDE drives */
...@@ -772,13 +771,12 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) ...@@ -772,13 +771,12 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
SELECT_DRIVE(drive); SELECT_DRIVE(drive);
SELECT_MASK(drive, 0); SELECT_MASK(drive, 0);
udelay(1); udelay(1);
if (IDE_CONTROL_REG) ide_set_irq(drive, 0);
hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
hwif->OUTB(speed, IDE_NSECTOR_REG); hwif->OUTB(speed, IDE_NSECTOR_REG);
hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG);
hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG);
if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) if (drive->quirk_list == 2)
hwif->OUTB(drive->ctl, IDE_CONTROL_REG); ide_set_irq(drive, 1);
error = __ide_wait_stat(drive, drive->ready_stat, error = __ide_wait_stat(drive, drive->ready_stat,
BUSY_STAT|DRQ_STAT|ERR_STAT, BUSY_STAT|DRQ_STAT|ERR_STAT,
...@@ -799,10 +797,11 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) ...@@ -799,10 +797,11 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
skip: skip:
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (speed >= XFER_SW_DMA_0) if ((speed >= XFER_SW_DMA_0 || (hwif->host_flags & IDE_HFLAG_VDMA)) &&
hwif->dma_host_on(drive); drive->using_dma)
else if (hwif->ide_dma_on) /* check if host supports DMA */ hwif->dma_host_set(drive, 1);
hwif->dma_off_quietly(drive); else if (hwif->dma_host_set) /* check if host supports DMA */
ide_dma_off_quietly(drive);
#endif #endif
switch(speed) { switch(speed) {
...@@ -1012,10 +1011,10 @@ static void check_dma_crc(ide_drive_t *drive) ...@@ -1012,10 +1011,10 @@ static void check_dma_crc(ide_drive_t *drive)
{ {
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (drive->crc_count) { if (drive->crc_count) {
drive->hwif->dma_off_quietly(drive); ide_dma_off_quietly(drive);
ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive)); ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive));
if (drive->current_speed >= XFER_SW_DMA_0) if (drive->current_speed >= XFER_SW_DMA_0)
(void) HWIF(drive)->ide_dma_on(drive); ide_dma_on(drive);
} else } else
ide_dma_off(drive); ide_dma_off(drive);
#endif #endif
......
...@@ -454,8 +454,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) ...@@ -454,8 +454,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
static void ide_dump_opcode(ide_drive_t *drive) static void ide_dump_opcode(ide_drive_t *drive)
{ {
struct request *rq; struct request *rq;
u8 opcode = 0; ide_task_t *task = NULL;
int found = 0;
spin_lock(&ide_lock); spin_lock(&ide_lock);
rq = NULL; rq = NULL;
...@@ -464,25 +463,15 @@ static void ide_dump_opcode(ide_drive_t *drive) ...@@ -464,25 +463,15 @@ static void ide_dump_opcode(ide_drive_t *drive)
spin_unlock(&ide_lock); spin_unlock(&ide_lock);
if (!rq) if (!rq)
return; return;
if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
char *args = rq->buffer; if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
if (args) { task = rq->special;
opcode = args[0];
found = 1;
}
} else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *args = rq->special;
if (args) {
opcode = args->tf.command;
found = 1;
}
}
printk("ide: failed opcode was: "); printk("ide: failed opcode was: ");
if (!found) if (task == NULL)
printk("unknown\n"); printk(KERN_CONT "unknown\n");
else else
printk("0x%02x\n", opcode); printk(KERN_CONT "0x%02x\n", task->tf.command);
} }
u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48) u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48)
......
...@@ -31,7 +31,6 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id ...@@ -31,7 +31,6 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
{ {
hw_regs_t hw; hw_regs_t hw;
ide_hwif_t *hwif; ide_hwif_t *hwif;
int index;
if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0))) if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0)))
return -1; return -1;
...@@ -41,11 +40,19 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id ...@@ -41,11 +40,19 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
pnp_port_start(dev, 1)); pnp_port_start(dev, 1));
hw.irq = pnp_irq(dev, 0); hw.irq = pnp_irq(dev, 0);
index = ide_register_hw(&hw, NULL, 1, &hwif); hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
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);
if (index != -1) { printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
pnp_set_drvdata(dev,hwif); pnp_set_drvdata(dev,hwif);
ide_device_add(idx);
return 0; return 0;
} }
...@@ -68,12 +75,15 @@ static struct pnp_driver idepnp_driver = { ...@@ -68,12 +75,15 @@ static struct pnp_driver idepnp_driver = {
.remove = idepnp_remove, .remove = idepnp_remove,
}; };
void __init pnpide_init(void) static int __init pnpide_init(void)
{ {
pnp_register_driver(&idepnp_driver); return pnp_register_driver(&idepnp_driver);
} }
void __exit pnpide_exit(void) static void __exit pnpide_exit(void)
{ {
pnp_unregister_driver(&idepnp_driver); pnp_unregister_driver(&idepnp_driver);
} }
module_init(pnpide_init);
module_exit(pnpide_exit);
...@@ -235,9 +235,6 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) ...@@ -235,9 +235,6 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
drive->media = ide_disk; drive->media = ide_disk;
printk("%s DISK drive\n", (id->config == 0x848a) ? "CFA" : "ATA" ); printk("%s DISK drive\n", (id->config == 0x848a) ? "CFA" : "ATA" );
if (hwif->quirkproc)
drive->quirk_list = hwif->quirkproc(drive);
return; return;
err_misc: err_misc:
...@@ -353,22 +350,19 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd) ...@@ -353,22 +350,19 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
* the irq handler isn't expecting. * the irq handler isn't expecting.
*/ */
if (IDE_CONTROL_REG) { if (IDE_CONTROL_REG) {
u8 ctl = drive->ctl | 2;
if (!hwif->irq) { if (!hwif->irq) {
autoprobe = 1; autoprobe = 1;
cookie = probe_irq_on(); cookie = probe_irq_on();
/* enable device irq */
ctl &= ~2;
} }
hwif->OUTB(ctl, IDE_CONTROL_REG); ide_set_irq(drive, autoprobe);
} }
retval = actual_try_to_identify(drive, cmd); retval = actual_try_to_identify(drive, cmd);
if (autoprobe) { if (autoprobe) {
int irq; int irq;
/* mask device irq */
hwif->OUTB(drive->ctl|2, IDE_CONTROL_REG); ide_set_irq(drive, 0);
/* clear drive IRQ */ /* clear drive IRQ */
(void) hwif->INB(IDE_STATUS_REG); (void) hwif->INB(IDE_STATUS_REG);
udelay(5); udelay(5);
...@@ -388,6 +382,20 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd) ...@@ -388,6 +382,20 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
return retval; return retval;
} }
static int ide_busy_sleep(ide_hwif_t *hwif)
{
unsigned long timeout = jiffies + WAIT_WORSTCASE;
u8 stat;
do {
msleep(50);
stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
if ((stat & BUSY_STAT) == 0)
return 0;
} while (time_before(jiffies, timeout));
return 1;
}
/** /**
* do_probe - probe an IDE device * do_probe - probe an IDE device
...@@ -456,7 +464,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -456,7 +464,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if ((rc == 1 && cmd == WIN_PIDENTIFY) && if ((rc == 1 && cmd == WIN_PIDENTIFY) &&
((drive->autotune == IDE_TUNE_DEFAULT) || ((drive->autotune == IDE_TUNE_DEFAULT) ||
(drive->autotune == IDE_TUNE_AUTO))) { (drive->autotune == IDE_TUNE_AUTO))) {
unsigned long timeout;
printk("%s: no response (status = 0x%02x), " printk("%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, "resetting drive\n", drive->name,
hwif->INB(IDE_STATUS_REG)); hwif->INB(IDE_STATUS_REG));
...@@ -464,10 +471,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -464,10 +471,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
hwif->OUTB(drive->select.all, IDE_SELECT_REG); hwif->OUTB(drive->select.all, IDE_SELECT_REG);
msleep(50); msleep(50);
hwif->OUTB(WIN_SRST, IDE_COMMAND_REG); hwif->OUTB(WIN_SRST, IDE_COMMAND_REG);
timeout = jiffies; (void)ide_busy_sleep(hwif);
while (((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) &&
time_before(jiffies, timeout + WAIT_WORSTCASE))
msleep(50);
rc = try_to_identify(drive, cmd); rc = try_to_identify(drive, cmd);
} }
if (rc == 1) if (rc == 1)
...@@ -495,20 +499,16 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -495,20 +499,16 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
static void enable_nest (ide_drive_t *drive) static void enable_nest (ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
unsigned long timeout;
printk("%s: enabling %s -- ", hwif->name, drive->id->model); printk("%s: enabling %s -- ", hwif->name, drive->id->model);
SELECT_DRIVE(drive); SELECT_DRIVE(drive);
msleep(50); msleep(50);
hwif->OUTB(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG); hwif->OUTB(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG);
timeout = jiffies + WAIT_WORSTCASE;
do { if (ide_busy_sleep(hwif)) {
if (time_after(jiffies, timeout)) { printk(KERN_CONT "failed (timeout)\n");
printk("failed (timeout)\n"); return;
return; }
}
msleep(50);
} while ((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT);
msleep(50); msleep(50);
...@@ -656,8 +656,7 @@ static int wait_hwif_ready(ide_hwif_t *hwif) ...@@ -656,8 +656,7 @@ static int wait_hwif_ready(ide_hwif_t *hwif)
/* Ignore disks that we will not probe for later. */ /* Ignore disks that we will not probe for later. */
if (!drive->noprobe || drive->present) { if (!drive->noprobe || drive->present) {
SELECT_DRIVE(drive); SELECT_DRIVE(drive);
if (IDE_CONTROL_REG) ide_set_irq(drive, 1);
hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
mdelay(2); mdelay(2);
rc = ide_wait_not_busy(hwif, 35000); rc = ide_wait_not_busy(hwif, 35000);
if (rc) if (rc)
...@@ -676,19 +675,18 @@ static int wait_hwif_ready(ide_hwif_t *hwif) ...@@ -676,19 +675,18 @@ static int wait_hwif_ready(ide_hwif_t *hwif)
/** /**
* ide_undecoded_slave - look for bad CF adapters * ide_undecoded_slave - look for bad CF adapters
* @hwif: interface * @drive1: drive
* *
* Analyse the drives on the interface and attempt to decide if we * Analyse the drives on the interface and attempt to decide if we
* have the same drive viewed twice. This occurs with crap CF adapters * have the same drive viewed twice. This occurs with crap CF adapters
* and PCMCIA sometimes. * and PCMCIA sometimes.
*/ */
void ide_undecoded_slave(ide_hwif_t *hwif) void ide_undecoded_slave(ide_drive_t *drive1)
{ {
ide_drive_t *drive0 = &hwif->drives[0]; ide_drive_t *drive0 = &drive1->hwif->drives[0];
ide_drive_t *drive1 = &hwif->drives[1];
if (drive0->present == 0 || drive1->present == 0) if ((drive1->dn & 1) == 0 || drive0->present == 0)
return; return;
/* If the models don't match they are not the same product */ /* If the models don't match they are not the same product */
...@@ -791,18 +789,11 @@ static void probe_hwif(ide_hwif_t *hwif) ...@@ -791,18 +789,11 @@ static void probe_hwif(ide_hwif_t *hwif)
} }
} }
if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) {
unsigned long timeout = jiffies + WAIT_WORSTCASE;
u8 stat;
printk(KERN_WARNING "%s: reset\n", hwif->name); printk(KERN_WARNING "%s: reset\n", hwif->name);
hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
udelay(10); udelay(10);
hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
do { (void)ide_busy_sleep(hwif);
msleep(50);
stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
} while ((stat & BUSY_STAT) && time_after(timeout, jiffies));
} }
local_irq_restore(flags); local_irq_restore(flags);
/* /*
...@@ -817,8 +808,12 @@ static void probe_hwif(ide_hwif_t *hwif) ...@@ -817,8 +808,12 @@ static void probe_hwif(ide_hwif_t *hwif)
return; return;
} }
if (hwif->fixup) for (unit = 0; unit < MAX_DRIVES; unit++) {
hwif->fixup(hwif); ide_drive_t *drive = &hwif->drives[unit];
if (drive->present && hwif->quirkproc)
hwif->quirkproc(drive);
}
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit]; ide_drive_t *drive = &hwif->drives[unit];
...@@ -833,7 +828,7 @@ static void probe_hwif(ide_hwif_t *hwif) ...@@ -833,7 +828,7 @@ static void probe_hwif(ide_hwif_t *hwif)
drive->nice1 = 1; drive->nice1 = 1;
if (hwif->ide_dma_on) if (hwif->dma_host_set)
ide_set_dma(drive); ide_set_dma(drive);
} }
} }
...@@ -848,25 +843,6 @@ static void probe_hwif(ide_hwif_t *hwif) ...@@ -848,25 +843,6 @@ static void probe_hwif(ide_hwif_t *hwif)
} }
} }
static int hwif_init(ide_hwif_t *hwif);
static void hwif_register_devices(ide_hwif_t *hwif);
static int probe_hwif_init(ide_hwif_t *hwif)
{
probe_hwif(hwif);
if (!hwif_init(hwif)) {
printk(KERN_INFO "%s: failed to initialize IDE interface\n",
hwif->name);
return -1;
}
if (hwif->present)
hwif_register_devices(hwif);
return 0;
}
#if MAX_HWIFS > 1 #if MAX_HWIFS > 1
/* /*
* save_match() is used to simplify logic in init_irq() below. * save_match() is used to simplify logic in init_irq() below.
...@@ -1359,54 +1335,63 @@ static void hwif_register_devices(ide_hwif_t *hwif) ...@@ -1359,54 +1335,63 @@ static void hwif_register_devices(ide_hwif_t *hwif)
} }
} }
int ideprobe_init (void) int ide_device_add_all(u8 *idx)
{ {
unsigned int index; ide_hwif_t *hwif;
int probe[MAX_HWIFS]; int i, rc = 0;
memset(probe, 0, MAX_HWIFS * sizeof(int)); for (i = 0; i < MAX_HWIFS; i++) {
for (index = 0; index < MAX_HWIFS; ++index) if (idx[i] == 0xff)
probe[index] = !ide_hwifs[index].present; continue;
for (index = 0; index < MAX_HWIFS; ++index) probe_hwif(&ide_hwifs[idx[i]]);
if (probe[index]) }
probe_hwif(&ide_hwifs[index]);
for (index = 0; index < MAX_HWIFS; ++index) for (i = 0; i < MAX_HWIFS; i++) {
if (probe[index]) if (idx[i] == 0xff)
hwif_init(&ide_hwifs[index]); continue;
for (index = 0; index < MAX_HWIFS; ++index) {
if (probe[index]) { hwif = &ide_hwifs[idx[i]];
ide_hwif_t *hwif = &ide_hwifs[index];
if (!hwif->present) if (hwif_init(hwif) == 0) {
continue; printk(KERN_INFO "%s: failed to initialize IDE "
if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced) "interface\n", hwif->name);
hwif->chipset = ide_generic; rc = -1;
hwif_register_devices(hwif); continue;
} }
} }
for (index = 0; index < MAX_HWIFS; ++index)
if (probe[index])
ide_proc_register_port(&ide_hwifs[index]);
return 0;
}
EXPORT_SYMBOL_GPL(ideprobe_init); for (i = 0; i < MAX_HWIFS; i++) {
if (idx[i] == 0xff)
continue;
int ide_device_add(u8 idx[4]) hwif = &ide_hwifs[idx[i]];
{
int i, rc = 0;
for (i = 0; i < 4; i++) { if (hwif->present) {
if (idx[i] != 0xff) if (hwif->chipset == ide_unknown ||
rc |= probe_hwif_init(&ide_hwifs[idx[i]]); hwif->chipset == ide_forced)
hwif->chipset = ide_generic;
hwif_register_devices(hwif);
}
} }
for (i = 0; i < 4; i++) { for (i = 0; i < MAX_HWIFS; i++) {
if (idx[i] != 0xff) if (idx[i] != 0xff)
ide_proc_register_port(&ide_hwifs[idx[i]]); ide_proc_register_port(&ide_hwifs[idx[i]]);
} }
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(ide_device_add_all);
int ide_device_add(u8 idx[4])
{
u8 idx_all[MAX_HWIFS];
int i;
for (i = 0; i < MAX_HWIFS; i++)
idx_all[i] = (i < 4) ? idx[i] : 0xff;
return ide_device_add_all(idx_all);
}
EXPORT_SYMBOL_GPL(ide_device_add); EXPORT_SYMBOL_GPL(ide_device_add);
...@@ -346,14 +346,20 @@ static int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int va ...@@ -346,14 +346,20 @@ static int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int va
static int set_xfer_rate (ide_drive_t *drive, int arg) static int set_xfer_rate (ide_drive_t *drive, int arg)
{ {
ide_task_t task;
int err; int err;
if (arg < 0 || arg > 70) if (arg < 0 || arg > 70)
return -EINVAL; return -EINVAL;
err = ide_wait_cmd(drive, memset(&task, 0, sizeof(task));
WIN_SETFEATURES, (u8) arg, task.tf.command = WIN_SETFEATURES;
SETFEATURES_XFER, 0, NULL); task.tf.feature = SETFEATURES_XFER;
task.tf.nsect = (u8)arg;
task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
IDE_TFLAG_IN_NSECT;
err = ide_no_data_taskfile(drive, &task);
if (!err && arg) { if (!err && arg) {
ide_set_xfer_rate(drive, (u8) arg); ide_set_xfer_rate(drive, (u8) arg);
......
/*
* support for probing IDE PCI devices in the PCI bus order
*
* Copyright (c) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (c) 1995-1998 Mark Lord
*
* May be copied or modified under the terms of the GNU General Public License
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>
/*
* Module interfaces
*/
static int pre_init = 1; /* Before first ordered IDE scan */
static LIST_HEAD(ide_pci_drivers);
/*
* __ide_pci_register_driver - attach IDE driver
* @driver: pci driver
* @module: owner module of the driver
*
* Registers a driver with the IDE layer. The IDE layer arranges that
* boot time setup is done in the expected device order and then
* hands the controllers off to the core PCI code to do the rest of
* the work.
*
* Returns are the same as for pci_register_driver
*/
int __ide_pci_register_driver(struct pci_driver *driver, struct module *module,
const char *mod_name)
{
if (!pre_init)
return __pci_register_driver(driver, module, mod_name);
driver->driver.owner = module;
list_add_tail(&driver->node, &ide_pci_drivers);
return 0;
}
EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
/**
* ide_scan_pcidev - find an IDE driver for a device
* @dev: PCI device to check
*
* Look for an IDE driver to handle the device we are considering.
* This is only used during boot up to get the ordering correct. After
* boot up the pci layer takes over the job.
*/
static int __init ide_scan_pcidev(struct pci_dev *dev)
{
struct list_head *l;
struct pci_driver *d;
list_for_each(l, &ide_pci_drivers) {
d = list_entry(l, struct pci_driver, node);
if (d->id_table) {
const struct pci_device_id *id =
pci_match_id(d->id_table, dev);
if (id != NULL && d->probe(dev, id) >= 0) {
dev->driver = d;
pci_dev_get(dev);
return 1;
}
}
}
return 0;
}
/**
* ide_scan_pcibus - perform the initial IDE driver scan
*
* Perform the initial bus rather than driver ordered scan of the
* PCI drivers. After this all IDE pci handling becomes standard
* module ordering not traditionally ordered.
*/
int __init ide_scan_pcibus(void)
{
struct pci_dev *dev = NULL;
struct pci_driver *d;
struct list_head *l, *n;
pre_init = 0;
if (!ide_scan_direction)
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
ide_scan_pcidev(dev);
else
while ((dev = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID,
dev)))
ide_scan_pcidev(dev);
/*
* Hand the drivers over to the PCI layer now we
* are post init.
*/
list_for_each_safe(l, n, &ide_pci_drivers) {
list_del(l);
d = list_entry(l, struct pci_driver, node);
if (__pci_register_driver(d, d->driver.owner,
d->driver.mod_name))
printk(KERN_ERR "%s: failed to register %s driver\n",
__FUNCTION__, d->driver.mod_name);
}
return 0;
}
static int __init ide_scan_pci(void)
{
return ide_scan_pcibus();
}
module_init(ide_scan_pci);
...@@ -1690,6 +1690,11 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) ...@@ -1690,6 +1690,11 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
if (error) if (error)
tape->failed_pc = NULL; tape->failed_pc = NULL;
if (!blk_special_request(rq)) {
ide_end_request(drive, uptodate, nr_sects);
return 0;
}
spin_lock_irqsave(&tape->spinlock, flags); spin_lock_irqsave(&tape->spinlock, flags);
/* The request was a pipelined data transfer request */ /* The request was a pipelined data transfer request */
......
...@@ -35,34 +35,6 @@ ...@@ -35,34 +35,6 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
static void ata_bswap_data (void *buffer, int wcount)
{
u16 *p = buffer;
while (wcount--) {
*p = *p << 8 | *p >> 8; p++;
*p = *p << 8 | *p >> 8; p++;
}
}
static void taskfile_input_data(ide_drive_t *drive, void *buffer, u32 wcount)
{
HWIF(drive)->ata_input_data(drive, buffer, wcount);
if (drive->bswap)
ata_bswap_data(buffer, wcount);
}
static void taskfile_output_data(ide_drive_t *drive, void *buffer, u32 wcount)
{
if (drive->bswap) {
ata_bswap_data(buffer, wcount);
HWIF(drive)->ata_output_data(drive, buffer, wcount);
ata_bswap_data(buffer, wcount);
} else {
HWIF(drive)->ata_output_data(drive, buffer, wcount);
}
}
void ide_tf_load(ide_drive_t *drive, ide_task_t *task) void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
{ {
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
...@@ -77,10 +49,13 @@ void ide_tf_load(ide_drive_t *drive, ide_task_t *task) ...@@ -77,10 +49,13 @@ void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
"lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n", "lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n",
drive->name, tf->feature, tf->nsect, tf->lbal, drive->name, tf->feature, tf->nsect, tf->lbal,
tf->lbam, tf->lbah, tf->device, tf->command); tf->lbam, tf->lbah, tf->device, tf->command);
printk("%s: hob: nsect 0x%02x lbal 0x%02x "
"lbam 0x%02x lbah 0x%02x\n",
drive->name, tf->hob_nsect, tf->hob_lbal,
tf->hob_lbam, tf->hob_lbah);
#endif #endif
if (IDE_CONTROL_REG) ide_set_irq(drive, 1);
hwif->OUTB(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0) if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0)
SELECT_MASK(drive, 0); SELECT_MASK(drive, 0);
...@@ -124,7 +99,7 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) ...@@ -124,7 +99,7 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
args.tf.command = WIN_IDENTIFY; args.tf.command = WIN_IDENTIFY;
else else
args.tf.command = WIN_PIDENTIFY; args.tf.command = WIN_PIDENTIFY;
args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
args.data_phase = TASKFILE_IN; args.data_phase = TASKFILE_IN;
return ide_raw_taskfile(drive, &args, buf, 1); return ide_raw_taskfile(drive, &args, buf, 1);
} }
...@@ -285,7 +260,7 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive) ...@@ -285,7 +260,7 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
return ide_stopped; return ide_stopped;
} }
static u8 wait_drive_not_busy(ide_drive_t *drive) u8 wait_drive_not_busy(ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
int retries; int retries;
...@@ -293,8 +268,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) ...@@ -293,8 +268,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
/* /*
* Last sector was transfered, wait until drive is ready. * Last sector was transfered, wait until drive is ready.
* This can take up to 10 usec, but we will wait max 1 ms * This can take up to 10 usec, but we will wait max 1 ms.
* (drive_cmd_intr() waits that long).
*/ */
for (retries = 0; retries < 100; retries++) { for (retries = 0; retries < 100; retries++) {
if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT)
...@@ -349,9 +323,9 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write) ...@@ -349,9 +323,9 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
/* do the actual data transfer */ /* do the actual data transfer */
if (write) if (write)
taskfile_output_data(drive, buf, SECTOR_WORDS); hwif->ata_output_data(drive, buf, SECTOR_WORDS);
else else
taskfile_input_data(drive, buf, SECTOR_WORDS); hwif->ata_input_data(drive, buf, SECTOR_WORDS);
kunmap_atomic(buf, KM_BIO_SRC_IRQ); kunmap_atomic(buf, KM_BIO_SRC_IRQ);
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
...@@ -371,9 +345,18 @@ static void ide_pio_multi(ide_drive_t *drive, unsigned int write) ...@@ -371,9 +345,18 @@ static void ide_pio_multi(ide_drive_t *drive, unsigned int write)
static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
unsigned int write) unsigned int write)
{ {
u8 saved_io_32bit = drive->io_32bit;
if (rq->bio) /* fs request */ if (rq->bio) /* fs request */
rq->errors = 0; rq->errors = 0;
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *task = rq->special;
if (task->tf_flags & IDE_TFLAG_IO_16BIT)
drive->io_32bit = 0;
}
touch_softlockup_watchdog(); touch_softlockup_watchdog();
switch (drive->hwif->data_phase) { switch (drive->hwif->data_phase) {
...@@ -385,6 +368,8 @@ static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, ...@@ -385,6 +368,8 @@ static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
ide_pio_sector(drive, write); ide_pio_sector(drive, write);
break; break;
} }
drive->io_32bit = saved_io_32bit;
} }
static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
...@@ -422,27 +407,22 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, ...@@ -422,27 +407,22 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
return ide_error(drive, s, stat); return ide_error(drive, s, stat);
} }
static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
{ {
HWIF(drive)->cursg = NULL;
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *task = rq->special; u8 err = drive->hwif->INB(IDE_ERROR_REG);
if (task->tf_flags & IDE_TFLAG_FLAGGED) { ide_end_drive_cmd(drive, stat, err);
u8 err = drive->hwif->INB(IDE_ERROR_REG); return;
ide_end_drive_cmd(drive, stat, err);
return;
}
} }
if (rq->rq_disk) { if (rq->rq_disk) {
ide_driver_t *drv; ide_driver_t *drv;
drv = *(ide_driver_t **)rq->rq_disk->private_data;; drv = *(ide_driver_t **)rq->rq_disk->private_data;;
drv->end_request(drive, 1, rq->hard_nr_sectors); drv->end_request(drive, 1, rq->nr_sectors);
} else } else
ide_end_request(drive, 1, rq->hard_nr_sectors); ide_end_request(drive, 1, rq->nr_sectors);
} }
/* /*
...@@ -455,7 +435,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive) ...@@ -455,7 +435,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
u8 stat = hwif->INB(IDE_STATUS_REG); u8 stat = hwif->INB(IDE_STATUS_REG);
/* new way for dealing with premature shared PCI interrupts */ /* new way for dealing with premature shared PCI interrupts */
if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) {
if (stat & (ERR_STAT | DRQ_STAT)) if (stat & (ERR_STAT | DRQ_STAT))
return task_error(drive, rq, __FUNCTION__, stat); return task_error(drive, rq, __FUNCTION__, stat);
/* No data yet, so wait for another IRQ. */ /* No data yet, so wait for another IRQ. */
...@@ -468,7 +448,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive) ...@@ -468,7 +448,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
/* If it was the last datablock check status and finish transfer. */ /* If it was the last datablock check status and finish transfer. */
if (!hwif->nleft) { if (!hwif->nleft) {
stat = wait_drive_not_busy(drive); stat = wait_drive_not_busy(drive);
if (!OK_STAT(stat, 0, BAD_R_STAT)) if (!OK_STAT(stat, 0, BAD_STAT))
return task_error(drive, rq, __FUNCTION__, stat); return task_error(drive, rq, __FUNCTION__, stat);
task_end_request(drive, rq, stat); task_end_request(drive, rq, stat);
return ide_stopped; return ide_stopped;
...@@ -512,7 +492,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) ...@@ -512,7 +492,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
{ {
ide_startstop_t startstop; ide_startstop_t startstop;
if (ide_wait_stat(&startstop, drive, DATA_READY, if (ide_wait_stat(&startstop, drive, DRQ_STAT,
drive->bad_wstat, WAIT_DRQ)) { drive->bad_wstat, WAIT_DRQ)) {
printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
drive->name, drive->name,
...@@ -580,7 +560,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -580,7 +560,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
unsigned int taskin = 0; unsigned int taskin = 0;
unsigned int taskout = 0; unsigned int taskout = 0;
u16 nsect = 0; u16 nsect = 0;
u8 io_32bit = drive->io_32bit;
char __user *buf = (char __user *)arg; char __user *buf = (char __user *)arg;
// printk("IDE Taskfile ...\n"); // printk("IDE Taskfile ...\n");
...@@ -633,9 +612,10 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -633,9 +612,10 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
args.data_phase = req_task->data_phase; args.data_phase = req_task->data_phase;
args.tf_flags = IDE_TFLAG_OUT_DEVICE; args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
IDE_TFLAG_IN_TF;
if (drive->addressing == 1) if (drive->addressing == 1)
args.tf_flags |= IDE_TFLAG_LBA48; args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
if (req_task->out_flags.all) { if (req_task->out_flags.all) {
args.tf_flags |= IDE_TFLAG_FLAGGED; args.tf_flags |= IDE_TFLAG_FLAGGED;
...@@ -671,7 +651,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -671,7 +651,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
if (req_task->in_flags.b.data) if (req_task->in_flags.b.data)
args.tf_flags |= IDE_TFLAG_IN_DATA; args.tf_flags |= IDE_TFLAG_IN_DATA;
drive->io_32bit = 0;
switch(req_task->data_phase) { switch(req_task->data_phase) {
case TASKFILE_MULTI_OUT: case TASKFILE_MULTI_OUT:
if (!drive->mult_count) { if (!drive->mult_count) {
...@@ -767,41 +746,24 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -767,41 +746,24 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
// printk("IDE Taskfile ioctl ended. rc = %i\n", err); // printk("IDE Taskfile ioctl ended. rc = %i\n", err);
drive->io_32bit = io_32bit;
return err; return err;
} }
#endif #endif
int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
{
struct request rq;
u8 buffer[4];
if (!buf)
buf = buffer;
memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors);
ide_init_drive_cmd(&rq);
rq.buffer = buf;
*buf++ = cmd;
*buf++ = nsect;
*buf++ = feature;
*buf++ = sectors;
return ide_do_drive_cmd(drive, &rq, ide_wait);
}
int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
{ {
int err = 0; u8 *buf = NULL;
u8 args[4], *argbuf = args; int bufsize = 0, err = 0;
u8 xfer_rate = 0; u8 args[4], xfer_rate = 0;
int argsize = 4;
ide_task_t tfargs; ide_task_t tfargs;
struct ide_taskfile *tf = &tfargs.tf; struct ide_taskfile *tf = &tfargs.tf;
if (NULL == (void *) arg) { if (NULL == (void *) arg) {
struct request rq; struct request rq;
ide_init_drive_cmd(&rq); ide_init_drive_cmd(&rq);
rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
return ide_do_drive_cmd(drive, &rq, ide_wait); return ide_do_drive_cmd(drive, &rq, ide_wait);
} }
...@@ -810,23 +772,39 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -810,23 +772,39 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
memset(&tfargs, 0, sizeof(ide_task_t)); memset(&tfargs, 0, sizeof(ide_task_t));
tf->feature = args[2]; tf->feature = args[2];
tf->nsect = args[3]; if (args[0] == WIN_SMART) {
tf->lbal = args[1]; tf->nsect = args[3];
tf->lbal = args[1];
tf->lbam = 0x4f;
tf->lbah = 0xc2;
tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
} else {
tf->nsect = args[1];
tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE |
IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT;
}
tf->command = args[0]; tf->command = args[0];
tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA;
if (args[3]) { if (args[3]) {
argsize = 4 + (SECTOR_WORDS * 4 * args[3]); tfargs.tf_flags |= IDE_TFLAG_IO_16BIT;
argbuf = kzalloc(argsize, GFP_KERNEL); bufsize = SECTOR_WORDS * 4 * args[3];
if (argbuf == NULL) buf = kzalloc(bufsize, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM; return -ENOMEM;
} }
if (set_transfer(drive, &tfargs)) { if (set_transfer(drive, &tfargs)) {
xfer_rate = args[1]; xfer_rate = args[1];
if (ide_ata66_check(drive, &tfargs)) if (ide_ata66_check(drive, &tfargs))
goto abort; goto abort;
} }
err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); err = ide_raw_taskfile(drive, &tfargs, buf, args[3]);
args[0] = tf->status;
args[1] = tf->error;
args[2] = tf->nsect;
if (!err && xfer_rate) { if (!err && xfer_rate) {
/* active-retuning-calls future */ /* active-retuning-calls future */
...@@ -834,10 +812,13 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -834,10 +812,13 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
ide_driveid_update(drive); ide_driveid_update(drive);
} }
abort: abort:
if (copy_to_user((void __user *)arg, argbuf, argsize)) if (copy_to_user((void __user *)arg, &args, 4))
err = -EFAULT; err = -EFAULT;
if (argsize > 4) if (buf) {
kfree(argbuf); if (copy_to_user((void __user *)(arg + 4), buf, bufsize))
err = -EFAULT;
kfree(buf);
}
return err; return err;
} }
...@@ -854,7 +835,7 @@ int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -854,7 +835,7 @@ int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
memset(&task, 0, sizeof(task)); memset(&task, 0, sizeof(task));
memcpy(&task.tf_array[7], &args[1], 6); memcpy(&task.tf_array[7], &args[1], 6);
task.tf.command = args[0]; task.tf.command = args[0];
task.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
err = ide_no_data_taskfile(drive, &task); err = ide_no_data_taskfile(drive, &task);
......
This diff is collapsed.
# link order is important here
obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o
obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o
obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o
obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o
obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o
obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o
obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o
obj-$(CONFIG_BLK_DEV_Q40IDE) += q40ide.o
obj-$(CONFIG_BLK_DEV_BUDDHA) += buddha.o
obj-$(CONFIG_BLK_DEV_PLATFORM) += ide_platform.o ifeq ($(CONFIG_BLK_DEV_IDECS), m)
obj-m += ide-cs.o
endif
# Last of all ifeq ($(CONFIG_BLK_DEV_PLATFORM), m)
obj-$(CONFIG_BLK_DEV_HD) += hd.o obj-m += ide_platform.o
endif
EXTRA_CFLAGS := -Idrivers/ide EXTRA_CFLAGS := -Idrivers/ide
...@@ -231,8 +231,7 @@ int probe_ali14xx = 0; ...@@ -231,8 +231,7 @@ int probe_ali14xx = 0;
module_param_named(probe, probe_ali14xx, bool, 0); module_param_named(probe, probe_ali14xx, bool, 0);
MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets"); MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets");
/* Can be called directly from ide.c. */ static int __init ali14xx_init(void)
int __init ali14xx_init(void)
{ {
if (probe_ali14xx == 0) if (probe_ali14xx == 0)
goto out; goto out;
...@@ -248,9 +247,7 @@ int __init ali14xx_init(void) ...@@ -248,9 +247,7 @@ int __init ali14xx_init(void)
return -ENODEV; return -ENODEV;
} }
#ifdef MODULE
module_init(ali14xx_init); module_init(ali14xx_init);
#endif
MODULE_AUTHOR("see local file"); MODULE_AUTHOR("see local file");
MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets"); MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets");
......
...@@ -112,6 +112,7 @@ typedef enum BuddhaType_Enum { ...@@ -112,6 +112,7 @@ typedef enum BuddhaType_Enum {
BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF
} BuddhaType; } BuddhaType;
static const char *buddha_board_name[] = { "Buddha", "Catweasel", "X-Surf" };
/* /*
* Check and acknowledge the interrupt status * Check and acknowledge the interrupt status
...@@ -143,11 +144,11 @@ static int xsurf_ack_intr(ide_hwif_t *hwif) ...@@ -143,11 +144,11 @@ static int xsurf_ack_intr(ide_hwif_t *hwif)
* Probe for a Buddha or Catweasel IDE interface * Probe for a Buddha or Catweasel IDE interface
*/ */
void __init buddha_init(void) static int __init buddha_init(void)
{ {
hw_regs_t hw; hw_regs_t hw;
ide_hwif_t *hwif; ide_hwif_t *hwif;
int i, index; int i;
struct zorro_dev *z = NULL; struct zorro_dev *z = NULL;
u_long buddha_board = 0; u_long buddha_board = 0;
...@@ -156,6 +157,8 @@ void __init buddha_init(void) ...@@ -156,6 +157,8 @@ void __init buddha_init(void)
while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
unsigned long board; unsigned long board;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) {
buddha_num_hwifs = BUDDHA_NUM_HWIFS; buddha_num_hwifs = BUDDHA_NUM_HWIFS;
type=BOARD_BUDDHA; type=BOARD_BUDDHA;
...@@ -195,7 +198,10 @@ void __init buddha_init(void) ...@@ -195,7 +198,10 @@ void __init buddha_init(void)
/* X-Surf doesn't have this. IRQs are always on */ /* X-Surf doesn't have this. IRQs are always on */
if (type != BOARD_XSURF) if (type != BOARD_XSURF)
z_writeb(0, buddha_board+BUDDHA_IRQ_MR); z_writeb(0, buddha_board+BUDDHA_IRQ_MR);
printk(KERN_INFO "ide: %s IDE controller\n",
buddha_board_name[type]);
for(i=0;i<buddha_num_hwifs;i++) { for(i=0;i<buddha_num_hwifs;i++) {
if(type != BOARD_XSURF) { if(type != BOARD_XSURF) {
ide_setup_ports(&hw, (buddha_board+buddha_bases[i]), ide_setup_ports(&hw, (buddha_board+buddha_bases[i]),
...@@ -213,23 +219,23 @@ void __init buddha_init(void) ...@@ -213,23 +219,23 @@ void __init buddha_init(void)
IRQ_AMIGA_PORTS); IRQ_AMIGA_PORTS);
} }
index = ide_register_hw(&hw, NULL, 1, &hwif); hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (index != -1) { if (hwif) {
u8 index = hwif->index;
ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
hwif->mmio = 1; hwif->mmio = 1;
printk("ide%d: ", index);
switch(type) { idx[i] = index;
case BOARD_BUDDHA: }
printk("Buddha");
break;
case BOARD_CATWEASEL:
printk("Catweasel");
break;
case BOARD_XSURF:
printk("X-Surf");
break;
}
printk(" IDE interface\n");
}
} }
ide_device_add(idx);
} }
return 0;
} }
module_init(buddha_init);
...@@ -150,8 +150,7 @@ int probe_dtc2278 = 0; ...@@ -150,8 +150,7 @@ int probe_dtc2278 = 0;
module_param_named(probe, probe_dtc2278, bool, 0); module_param_named(probe, probe_dtc2278, bool, 0);
MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets"); MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets");
/* Can be called directly from ide.c. */ static int __init dtc2278_init(void)
int __init dtc2278_init(void)
{ {
if (probe_dtc2278 == 0) if (probe_dtc2278 == 0)
return -ENODEV; return -ENODEV;
...@@ -163,9 +162,7 @@ int __init dtc2278_init(void) ...@@ -163,9 +162,7 @@ int __init dtc2278_init(void)
return 0; return 0;
} }
#ifdef MODULE
module_init(dtc2278_init); module_init(dtc2278_init);
#endif
MODULE_AUTHOR("See Local File"); MODULE_AUTHOR("See Local File");
MODULE_DESCRIPTION("support of DTC-2278 VLB IDE chipsets"); MODULE_DESCRIPTION("support of DTC-2278 VLB IDE chipsets");
......
...@@ -62,19 +62,31 @@ EXPORT_SYMBOL(falconide_intr_lock); ...@@ -62,19 +62,31 @@ EXPORT_SYMBOL(falconide_intr_lock);
* Probe for a Falcon IDE interface * Probe for a Falcon IDE interface
*/ */
void __init falconide_init(void) static int __init falconide_init(void)
{ {
if (MACH_IS_ATARI && ATARIHW_PRESENT(IDE)) { if (MACH_IS_ATARI && ATARIHW_PRESENT(IDE)) {
hw_regs_t hw; hw_regs_t hw;
int index;
printk(KERN_INFO "ide: Falcon IDE controller\n");
ide_setup_ports(&hw, ATA_HD_BASE, falconide_offsets, ide_setup_ports(&hw, ATA_HD_BASE, falconide_offsets,
0, 0, NULL, 0, 0, NULL,
// falconide_iops, // falconide_iops,
IRQ_MFP_IDE); IRQ_MFP_IDE);
index = ide_register_hw(&hw, NULL, 1, NULL);
if (index != -1) hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
printk("ide%d: Falcon IDE interface\n", index); 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);
ide_device_add(idx);
}
} }
return 0;
} }
module_init(falconide_init);
...@@ -110,12 +110,13 @@ static int gayle_ack_intr_a1200(ide_hwif_t *hwif) ...@@ -110,12 +110,13 @@ static int gayle_ack_intr_a1200(ide_hwif_t *hwif)
* Probe for a Gayle IDE interface (and optionally for an IDE doubler) * Probe for a Gayle IDE interface (and optionally for an IDE doubler)
*/ */
void __init gayle_init(void) static int __init gayle_init(void)
{ {
int a4000, i; int a4000, i;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
if (!MACH_IS_AMIGA) if (!MACH_IS_AMIGA)
return; return -ENODEV;
if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE)) if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE))
goto found; goto found;
...@@ -125,15 +126,21 @@ void __init gayle_init(void) ...@@ -125,15 +126,21 @@ void __init gayle_init(void)
NULL)) NULL))
goto found; goto found;
#endif #endif
return; return -ENODEV;
found: found:
printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n",
a4000 ? 4000 : 1200,
#ifdef CONFIG_BLK_DEV_IDEDOUBLER
ide_doubler ? ", IDE doubler" :
#endif
"");
for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
unsigned long base, ctrlport, irqport; unsigned long base, ctrlport, irqport;
ide_ack_intr_t *ack_intr; ide_ack_intr_t *ack_intr;
hw_regs_t hw; hw_regs_t hw;
ide_hwif_t *hwif; ide_hwif_t *hwif;
int index;
unsigned long phys_base, res_start, res_n; unsigned long phys_base, res_start, res_n;
if (a4000) { if (a4000) {
...@@ -165,21 +172,23 @@ void __init gayle_init(void) ...@@ -165,21 +172,23 @@ void __init gayle_init(void)
// &gayle_iops, // &gayle_iops,
IRQ_AMIGA_PORTS); IRQ_AMIGA_PORTS);
index = ide_register_hw(&hw, NULL, 1, &hwif); hwif = ide_find_port(base);
if (index != -1) { if (hwif) {
u8 index = hwif->index;
ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
hwif->mmio = 1; hwif->mmio = 1;
switch (i) {
case 0: idx[i] = index;
printk("ide%d: Gayle IDE interface (A%d style)\n", index,
a4000 ? 4000 : 1200);
break;
#ifdef CONFIG_BLK_DEV_IDEDOUBLER
case 1:
printk("ide%d: IDE doubler\n", index);
break;
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
}
} else } else
release_mem_region(res_start, res_n); release_mem_region(res_start, res_n);
} }
ide_device_add(idx);
return 0;
} }
module_init(gayle_init);
...@@ -307,8 +307,7 @@ int probe_ht6560b = 0; ...@@ -307,8 +307,7 @@ int probe_ht6560b = 0;
module_param_named(probe, probe_ht6560b, bool, 0); module_param_named(probe, probe_ht6560b, bool, 0);
MODULE_PARM_DESC(probe, "probe for HT6560B chipset"); MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
/* Can be called directly from ide.c. */ static int __init ht6560b_init(void)
int __init ht6560b_init(void)
{ {
ide_hwif_t *hwif, *mate; ide_hwif_t *hwif, *mate;
static u8 idx[4] = { 0, 1, 0xff, 0xff }; static u8 idx[4] = { 0, 1, 0xff, 0xff };
...@@ -369,9 +368,7 @@ int __init ht6560b_init(void) ...@@ -369,9 +368,7 @@ int __init ht6560b_init(void)
return -ENODEV; return -ENODEV;
} }
#ifdef MODULE
module_init(ht6560b_init); module_init(ht6560b_init);
#endif
MODULE_AUTHOR("See Local File"); MODULE_AUTHOR("See Local File");
MODULE_DESCRIPTION("HT-6560B EIDE-controller support"); MODULE_DESCRIPTION("HT-6560B EIDE-controller support");
......
...@@ -153,7 +153,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq ...@@ -153,7 +153,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq
hw.irq = irq; hw.irq = irq;
hw.chipset = ide_pci; hw.chipset = ide_pci;
hw.dev = &handle->dev; hw.dev = &handle->dev;
return ide_register_hw(&hw, &ide_undecoded_slave, 0, NULL); return ide_register_hw(&hw, &ide_undecoded_slave, NULL);
} }
/*====================================================================== /*======================================================================
......
...@@ -28,39 +28,27 @@ static struct { ...@@ -28,39 +28,27 @@ static struct {
int index; int index;
} hwif_prop; } hwif_prop;
static ide_hwif_t *__devinit plat_ide_locate_hwif(void __iomem *base, static void __devinit plat_ide_setup_ports(hw_regs_t *hw,
void __iomem *ctrl, struct pata_platform_info *pdata, int irq, void __iomem *base,
int mmio) void __iomem *ctrl,
struct pata_platform_info *pdata,
int irq)
{ {
unsigned long port = (unsigned long)base; unsigned long port = (unsigned long)base;
ide_hwif_t *hwif = ide_find_port(port);
int i; int i;
if (hwif == NULL) hw->io_ports[IDE_DATA_OFFSET] = port;
goto out;
hwif->io_ports[IDE_DATA_OFFSET] = port;
port += (1 << pdata->ioport_shift); port += (1 << pdata->ioport_shift);
for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET; for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET;
i++, port += (1 << pdata->ioport_shift)) i++, port += (1 << pdata->ioport_shift))
hwif->io_ports[i] = port; hw->io_ports[i] = port;
hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
hwif->irq = irq; hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
hwif->chipset = ide_generic; hw->irq = irq;
if (mmio) { hw->chipset = ide_generic;
hwif->mmio = 1;
default_hwif_mmiops(hwif);
}
hwif_prop.hwif = hwif;
hwif_prop.index = hwif->index;
out:
return hwif;
} }
static int __devinit plat_ide_probe(struct platform_device *pdev) static int __devinit plat_ide_probe(struct platform_device *pdev)
...@@ -71,6 +59,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) ...@@ -71,6 +59,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
int ret = 0; int ret = 0;
int mmio = 0; int mmio = 0;
hw_regs_t hw;
pdata = pdev->dev.platform_data; pdata = pdev->dev.platform_data;
...@@ -106,15 +95,27 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) ...@@ -106,15 +95,27 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
res_alt->start, res_alt->end - res_alt->start + 1); res_alt->start, res_alt->end - res_alt->start + 1);
} }
hwif = plat_ide_locate_hwif(hwif_prop.plat_ide_mapbase, hwif = ide_find_port((unsigned long)hwif_prop.plat_ide_mapbase);
hwif_prop.plat_ide_alt_mapbase, pdata, res_irq->start, mmio);
if (!hwif) { if (!hwif) {
ret = -ENODEV; ret = -ENODEV;
goto out; goto out;
} }
hwif->gendev.parent = &pdev->dev;
hwif->noprobe = 0; memset(&hw, 0, sizeof(hw));
plat_ide_setup_ports(&hw, hwif_prop.plat_ide_mapbase,
hwif_prop.plat_ide_alt_mapbase,
pdata, res_irq->start);
hw.dev = &pdev->dev;
ide_init_port_hw(hwif, &hw);
if (mmio) {
hwif->mmio = 1;
default_hwif_mmiops(hwif);
}
hwif_prop.hwif = hwif;
hwif_prop.index = hwif->index;
idx[0] = hwif->index; idx[0] = hwif->index;
......
...@@ -77,15 +77,17 @@ int macide_ack_intr(ide_hwif_t* hwif) ...@@ -77,15 +77,17 @@ int macide_ack_intr(ide_hwif_t* hwif)
return 0; return 0;
} }
static const char *mac_ide_name[] =
{ "Quadra", "Powerbook", "Powerbook Baboon" };
/* /*
* Probe for a Macintosh IDE interface * Probe for a Macintosh IDE interface
*/ */
void __init macide_init(void) static int __init macide_init(void)
{ {
hw_regs_t hw; hw_regs_t hw;
ide_hwif_t *hwif; ide_hwif_t *hwif;
int index = -1;
switch (macintosh_config->ide_type) { switch (macintosh_config->ide_type) {
case MAC_IDE_QUADRA: case MAC_IDE_QUADRA:
...@@ -93,48 +95,50 @@ void __init macide_init(void) ...@@ -93,48 +95,50 @@ void __init macide_init(void)
0, 0, macide_ack_intr, 0, 0, macide_ack_intr,
// quadra_ide_iops, // quadra_ide_iops,
IRQ_NUBUS_F); IRQ_NUBUS_F);
index = ide_register_hw(&hw, NULL, 1, &hwif);
break; break;
case MAC_IDE_PB: case MAC_IDE_PB:
ide_setup_ports(&hw, IDE_BASE, macide_offsets, ide_setup_ports(&hw, IDE_BASE, macide_offsets,
0, 0, macide_ack_intr, 0, 0, macide_ack_intr,
// macide_pb_iops, // macide_pb_iops,
IRQ_NUBUS_C); IRQ_NUBUS_C);
index = ide_register_hw(&hw, NULL, 1, &hwif);
break; break;
case MAC_IDE_BABOON: case MAC_IDE_BABOON:
ide_setup_ports(&hw, BABOON_BASE, macide_offsets, ide_setup_ports(&hw, BABOON_BASE, macide_offsets,
0, 0, NULL, 0, 0, NULL,
// macide_baboon_iops, // macide_baboon_iops,
IRQ_BABOON_1); IRQ_BABOON_1);
index = ide_register_hw(&hw, NULL, 1, &hwif); break;
if (index == -1) break; default:
if (macintosh_config->ident == MAC_MODEL_PB190) { return -ENODEV;
}
printk(KERN_INFO "ide: Macintosh %s IDE controller\n",
mac_ide_name[macintosh_config->ide_type - 1]);
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
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);
if (macintosh_config->ide_type == MAC_IDE_BABOON &&
macintosh_config->ident == MAC_MODEL_PB190) {
/* Fix breakage in ide-disk.c: drive capacity */ /* Fix breakage in ide-disk.c: drive capacity */
/* is not initialized for drives without a */ /* is not initialized for drives without a */
/* hardware ID, and we can't get that without */ /* hardware ID, and we can't get that without */
/* probing the drive which freezes a 190. */ /* probing the drive which freezes a 190. */
ide_drive_t *drive = &hwif->drives[0];
ide_drive_t *drive = &ide_hwifs[index].drives[0];
drive->capacity64 = drive->cyl*drive->head*drive->sect; drive->capacity64 = drive->cyl*drive->head*drive->sect;
} }
break;
default:
return;
}
if (index != -1) {
hwif->mmio = 1; hwif->mmio = 1;
if (macintosh_config->ide_type == MAC_IDE_QUADRA)
printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index); ide_device_add(idx);
else if (macintosh_config->ide_type == MAC_IDE_PB)
printk(KERN_INFO "ide%d: Macintosh Powerbook IDE interface\n", index);
else if (macintosh_config->ide_type == MAC_IDE_BABOON)
printk(KERN_INFO "ide%d: Macintosh Powerbook Baboon IDE interface\n", index);
else
printk(KERN_INFO "ide%d: Unknown Macintosh IDE interface\n", index);
} }
return 0;
} }
module_init(macide_init);
...@@ -111,15 +111,17 @@ static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={ ...@@ -111,15 +111,17 @@ static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={
* Probe for Q40 IDE interfaces * Probe for Q40 IDE interfaces
*/ */
void __init q40ide_init(void) static int __init q40ide_init(void)
{ {
int i; int i;
ide_hwif_t *hwif; ide_hwif_t *hwif;
int index;
const char *name; const char *name;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
if (!MACH_IS_Q40) if (!MACH_IS_Q40)
return ; return -ENODEV;
printk(KERN_INFO "ide: Q40 IDE controller\n");
for (i = 0; i < Q40IDE_NUM_HWIFS; i++) { for (i = 0; i < Q40IDE_NUM_HWIFS; i++) {
hw_regs_t hw; hw_regs_t hw;
...@@ -141,10 +143,20 @@ void __init q40ide_init(void) ...@@ -141,10 +143,20 @@ void __init q40ide_init(void)
0, NULL, 0, NULL,
// m68kide_iops, // m68kide_iops,
q40ide_default_irq(pcide_bases[i])); q40ide_default_irq(pcide_bases[i]));
index = ide_register_hw(&hw, NULL, 1, &hwif);
// **FIXME** hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (index != -1) if (hwif) {
ide_init_port_data(hwif, hwif->index);
ide_init_port_hw(hwif, &hw);
hwif->mmio = 1; hwif->mmio = 1;
idx[i] = hwif->index;
}
} }
ide_device_add(idx);
return 0;
} }
module_init(q40ide_init);
...@@ -478,8 +478,7 @@ int probe_qd65xx = 0; ...@@ -478,8 +478,7 @@ int probe_qd65xx = 0;
module_param_named(probe, probe_qd65xx, bool, 0); module_param_named(probe, probe_qd65xx, bool, 0);
MODULE_PARM_DESC(probe, "probe for QD65xx chipsets"); MODULE_PARM_DESC(probe, "probe for QD65xx chipsets");
/* Can be called directly from ide.c. */ static int __init qd65xx_init(void)
int __init qd65xx_init(void)
{ {
if (probe_qd65xx == 0) if (probe_qd65xx == 0)
return -ENODEV; return -ENODEV;
...@@ -492,9 +491,7 @@ int __init qd65xx_init(void) ...@@ -492,9 +491,7 @@ int __init qd65xx_init(void)
return 0; return 0;
} }
#ifdef MODULE
module_init(qd65xx_init); module_init(qd65xx_init);
#endif
MODULE_AUTHOR("Samuel Thibault"); MODULE_AUTHOR("Samuel Thibault");
MODULE_DESCRIPTION("support of qd65xx vlb ide chipset"); MODULE_DESCRIPTION("support of qd65xx vlb ide chipset");
......
...@@ -169,8 +169,7 @@ int probe_umc8672 = 0; ...@@ -169,8 +169,7 @@ int probe_umc8672 = 0;
module_param_named(probe, probe_umc8672, bool, 0); module_param_named(probe, probe_umc8672, bool, 0);
MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); MODULE_PARM_DESC(probe, "probe for UMC8672 chipset");
/* Can be called directly from ide.c. */ static int __init umc8672_init(void)
int __init umc8672_init(void)
{ {
if (probe_umc8672 == 0) if (probe_umc8672 == 0)
goto out; goto out;
...@@ -181,9 +180,7 @@ int __init umc8672_init(void) ...@@ -181,9 +180,7 @@ int __init umc8672_init(void)
return -ENODEV;; return -ENODEV;;
} }
#ifdef MODULE
module_init(umc8672_init); module_init(umc8672_init);
#endif
MODULE_AUTHOR("Wolfram Podien"); MODULE_AUTHOR("Wolfram Podien");
MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset"); MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset");
......
...@@ -395,26 +395,10 @@ static int auide_dma_test_irq(ide_drive_t *drive) ...@@ -395,26 +395,10 @@ static int auide_dma_test_irq(ide_drive_t *drive)
return 0; return 0;
} }
static void auide_dma_host_on(ide_drive_t *drive) static void auide_dma_host_set(ide_drive_t *drive, int on)
{ {
} }
static int auide_dma_on(ide_drive_t *drive)
{
drive->using_dma = 1;
return 0;
}
static void auide_dma_host_off(ide_drive_t *drive)
{
}
static void auide_dma_off_quietly(ide_drive_t *drive)
{
drive->using_dma = 0;
}
static void auide_dma_lost_irq(ide_drive_t *drive) static void auide_dma_lost_irq(ide_drive_t *drive)
{ {
printk(KERN_ERR "%s: IRQ lost\n", drive->name); printk(KERN_ERR "%s: IRQ lost\n", drive->name);
...@@ -641,12 +625,13 @@ static int au_ide_probe(struct device *dev) ...@@ -641,12 +625,13 @@ static int au_ide_probe(struct device *dev)
/* FIXME: This might possibly break PCMCIA IDE devices */ /* FIXME: This might possibly break PCMCIA IDE devices */
hwif = &ide_hwifs[pdev->id]; hwif = &ide_hwifs[pdev->id];
hwif->irq = ahwif->irq;
hwif->chipset = ide_au1xxx;
memset(&hw, 0, sizeof(hw)); memset(&hw, 0, sizeof(hw));
auide_setup_ports(&hw, ahwif); auide_setup_ports(&hw, ahwif);
memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports)); hw.irq = ahwif->irq;
hw.chipset = ide_au1xxx;
ide_init_port_hw(hwif, &hw);
hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
...@@ -660,7 +645,6 @@ static int au_ide_probe(struct device *dev) ...@@ -660,7 +645,6 @@ static int au_ide_probe(struct device *dev)
hwif->pio_mask = ATA_PIO4; hwif->pio_mask = ATA_PIO4;
hwif->host_flags = IDE_HFLAG_POST_SET_MODE; hwif->host_flags = IDE_HFLAG_POST_SET_MODE;
hwif->noprobe = 0;
hwif->drives[0].unmask = 1; hwif->drives[0].unmask = 1;
hwif->drives[1].unmask = 1; hwif->drives[1].unmask = 1;
...@@ -682,29 +666,25 @@ static int au_ide_probe(struct device *dev) ...@@ -682,29 +666,25 @@ static int au_ide_probe(struct device *dev)
hwif->set_dma_mode = &auide_set_dma_mode; hwif->set_dma_mode = &auide_set_dma_mode;
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
hwif->dma_off_quietly = &auide_dma_off_quietly;
hwif->dma_timeout = &auide_dma_timeout; hwif->dma_timeout = &auide_dma_timeout;
hwif->mdma_filter = &auide_mdma_filter; hwif->mdma_filter = &auide_mdma_filter;
hwif->dma_host_set = &auide_dma_host_set;
hwif->dma_exec_cmd = &auide_dma_exec_cmd; hwif->dma_exec_cmd = &auide_dma_exec_cmd;
hwif->dma_start = &auide_dma_start; hwif->dma_start = &auide_dma_start;
hwif->ide_dma_end = &auide_dma_end; hwif->ide_dma_end = &auide_dma_end;
hwif->dma_setup = &auide_dma_setup; hwif->dma_setup = &auide_dma_setup;
hwif->ide_dma_test_irq = &auide_dma_test_irq; hwif->ide_dma_test_irq = &auide_dma_test_irq;
hwif->dma_host_off = &auide_dma_host_off;
hwif->dma_host_on = &auide_dma_host_on;
hwif->dma_lost_irq = &auide_dma_lost_irq; hwif->dma_lost_irq = &auide_dma_lost_irq;
hwif->ide_dma_on = &auide_dma_on; #endif
#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
hwif->channel = 0; hwif->channel = 0;
hwif->hold = 1;
hwif->select_data = 0; /* no chipset-specific code */ hwif->select_data = 0; /* no chipset-specific code */
hwif->config_data = 0; /* no chipset-specific code */ hwif->config_data = 0; /* no chipset-specific code */
hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */ hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */
hwif->drives[1].autotune = 1; hwif->drives[1].autotune = 1;
#endif
hwif->drives[0].no_io_32bit = 1; hwif->drives[0].no_io_32bit = 1;
hwif->drives[1].no_io_32bit = 1; hwif->drives[1].no_io_32bit = 1;
......
...@@ -117,6 +117,7 @@ static int __devinit swarm_ide_probe(struct device *dev) ...@@ -117,6 +117,7 @@ static int __devinit swarm_ide_probe(struct device *dev)
default_hwif_mmiops(hwif); default_hwif_mmiops(hwif);
/* Prevent resource map manipulation. */ /* Prevent resource map manipulation. */
hwif->mmio = 1; hwif->mmio = 1;
hwif->chipset = ide_generic;
hwif->noprobe = 0; hwif->noprobe = 0;
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
......
...@@ -36,4 +36,8 @@ obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o ...@@ -36,4 +36,8 @@ obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o
# Must appear at the end of the block # Must appear at the end of the block
obj-$(CONFIG_BLK_DEV_GENERIC) += generic.o obj-$(CONFIG_BLK_DEV_GENERIC) += generic.o
ifeq ($(CONFIG_BLK_DEV_CMD640), m)
obj-m += cmd640.o
endif
EXTRA_CFLAGS := -Idrivers/ide EXTRA_CFLAGS := -Idrivers/ide
/* /*
* linux/drivers/ide/pci/atiixp.c Version 0.03 Aug 3 2007 * linux/drivers/ide/pci/atiixp.c Version 0.05 Nov 9 2007
* *
* Copyright (C) 2003 ATI Inc. <hyu@ati.com> * Copyright (C) 2003 ATI Inc. <hyu@ati.com>
* Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz * Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz
...@@ -43,47 +43,8 @@ static atiixp_ide_timing mdma_timing[] = { ...@@ -43,47 +43,8 @@ static atiixp_ide_timing mdma_timing[] = {
{ 0x02, 0x00 }, { 0x02, 0x00 },
}; };
static int save_mdma_mode[4];
static DEFINE_SPINLOCK(atiixp_lock); static DEFINE_SPINLOCK(atiixp_lock);
static void atiixp_dma_host_on(ide_drive_t *drive)
{
struct pci_dev *dev = drive->hwif->pci_dev;
unsigned long flags;
u16 tmp16;
spin_lock_irqsave(&atiixp_lock, flags);
pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
if (save_mdma_mode[drive->dn])
tmp16 &= ~(1 << drive->dn);
else
tmp16 |= (1 << drive->dn);
pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
spin_unlock_irqrestore(&atiixp_lock, flags);
ide_dma_host_on(drive);
}
static void atiixp_dma_host_off(ide_drive_t *drive)
{
struct pci_dev *dev = drive->hwif->pci_dev;
unsigned long flags;
u16 tmp16;
spin_lock_irqsave(&atiixp_lock, flags);
pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
tmp16 &= ~(1 << drive->dn);
pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
spin_unlock_irqrestore(&atiixp_lock, flags);
ide_dma_host_off(drive);
}
/** /**
* atiixp_set_pio_mode - set host controller for PIO mode * atiixp_set_pio_mode - set host controller for PIO mode
* @drive: drive * @drive: drive
...@@ -132,26 +93,33 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed) ...@@ -132,26 +93,33 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
u32 tmp32; u32 tmp32;
u16 tmp16; u16 tmp16;
u16 udma_ctl = 0;
spin_lock_irqsave(&atiixp_lock, flags); spin_lock_irqsave(&atiixp_lock, flags);
save_mdma_mode[drive->dn] = 0; pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &udma_ctl);
if (speed >= XFER_UDMA_0) { if (speed >= XFER_UDMA_0) {
pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16); pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16);
tmp16 &= ~(0x07 << (drive->dn * 4)); tmp16 &= ~(0x07 << (drive->dn * 4));
tmp16 |= ((speed & 0x07) << (drive->dn * 4)); tmp16 |= ((speed & 0x07) << (drive->dn * 4));
pci_write_config_word(dev, ATIIXP_IDE_UDMA_MODE, tmp16); pci_write_config_word(dev, ATIIXP_IDE_UDMA_MODE, tmp16);
} else {
if ((speed >= XFER_MW_DMA_0) && (speed <= XFER_MW_DMA_2)) { udma_ctl |= (1 << drive->dn);
save_mdma_mode[drive->dn] = speed; } else if (speed >= XFER_MW_DMA_0) {
pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32); u8 i = speed & 0x03;
tmp32 &= ~(0xff << timing_shift);
tmp32 |= (mdma_timing[speed & 0x03].recover_width << timing_shift) | pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32);
(mdma_timing[speed & 0x03].command_width << (timing_shift + 4)); tmp32 &= ~(0xff << timing_shift);
pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32); tmp32 |= (mdma_timing[i].recover_width << timing_shift) |
} (mdma_timing[i].command_width << (timing_shift + 4));
pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32);
udma_ctl &= ~(1 << drive->dn);
} }
pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, udma_ctl);
spin_unlock_irqrestore(&atiixp_lock, flags); spin_unlock_irqrestore(&atiixp_lock, flags);
} }
...@@ -181,9 +149,6 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) ...@@ -181,9 +149,6 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
hwif->cbl = ATA_CBL_PATA80; hwif->cbl = ATA_CBL_PATA80;
else else
hwif->cbl = ATA_CBL_PATA40; hwif->cbl = ATA_CBL_PATA40;
hwif->dma_host_on = &atiixp_dma_host_on;
hwif->dma_host_off = &atiixp_dma_host_off;
} }
static const struct ide_port_info atiixp_pci_info[] __devinitdata = { static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
......
...@@ -706,9 +706,9 @@ static int pci_conf2(void) ...@@ -706,9 +706,9 @@ static int pci_conf2(void)
} }
/* /*
* Probe for a cmd640 chipset, and initialize it if found. Called from ide.c * Probe for a cmd640 chipset, and initialize it if found.
*/ */
int __init ide_probe_for_cmd640x (void) static int __init cmd640x_init(void)
{ {
#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
int second_port_toggled = 0; int second_port_toggled = 0;
...@@ -717,6 +717,7 @@ int __init ide_probe_for_cmd640x (void) ...@@ -717,6 +717,7 @@ int __init ide_probe_for_cmd640x (void)
const char *bus_type, *port2; const char *bus_type, *port2;
unsigned int index; unsigned int index;
u8 b, cfr; u8 b, cfr;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
if (cmd640_vlb && probe_for_cmd640_vlb()) { if (cmd640_vlb && probe_for_cmd640_vlb()) {
bus_type = "VLB"; bus_type = "VLB";
...@@ -769,6 +770,8 @@ int __init ide_probe_for_cmd640x (void) ...@@ -769,6 +770,8 @@ int __init ide_probe_for_cmd640x (void)
cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode; cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode;
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
idx[0] = cmd_hwif0->index;
/* /*
* Ensure compatibility by always using the slowest timings * Ensure compatibility by always using the slowest timings
* for access to the drive's command register block, * for access to the drive's command register block,
...@@ -826,6 +829,8 @@ int __init ide_probe_for_cmd640x (void) ...@@ -826,6 +829,8 @@ int __init ide_probe_for_cmd640x (void)
cmd_hwif1->pio_mask = ATA_PIO5; cmd_hwif1->pio_mask = ATA_PIO5;
cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode; cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode;
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
idx[1] = cmd_hwif1->index;
} }
printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name, printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name,
cmd_hwif0->serialized ? "" : "not ", port2); cmd_hwif0->serialized ? "" : "not ", port2);
...@@ -872,6 +877,13 @@ int __init ide_probe_for_cmd640x (void) ...@@ -872,6 +877,13 @@ int __init ide_probe_for_cmd640x (void)
#ifdef CMD640_DUMP_REGS #ifdef CMD640_DUMP_REGS
cmd640_dump_regs(); cmd640_dump_regs();
#endif #endif
ide_device_add(idx);
return 1; return 1;
} }
module_param_named(probe_vlb, cmd640_vlb, bool, 0);
MODULE_PARM_DESC(probe_vlb, "probe for VLB version of CMD640 chipset");
module_init(cmd640x_init);
/* /*
* linux/drivers/ide/pci/cmd64x.c Version 1.52 Dec 24, 2007 * linux/drivers/ide/pci/cmd64x.c Version 1.53 Dec 24, 2007
* *
* cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
* Due to massive hardware bugs, UltraDMA is only supported * Due to massive hardware bugs, UltraDMA is only supported
...@@ -22,8 +22,6 @@ ...@@ -22,8 +22,6 @@
#include <asm/io.h> #include <asm/io.h>
#define DISPLAY_CMD64X_TIMINGS
#define CMD_DEBUG 0 #define CMD_DEBUG 0
#if CMD_DEBUG #if CMD_DEBUG
...@@ -37,11 +35,6 @@ ...@@ -37,11 +35,6 @@
*/ */
#define CFR 0x50 #define CFR 0x50
#define CFR_INTR_CH0 0x04 #define CFR_INTR_CH0 0x04
#define CNTRL 0x51
#define CNTRL_ENA_1ST 0x04
#define CNTRL_ENA_2ND 0x08
#define CNTRL_DIS_RA0 0x40
#define CNTRL_DIS_RA1 0x80
#define CMDTIM 0x52 #define CMDTIM 0x52
#define ARTTIM0 0x53 #define ARTTIM0 0x53
...@@ -60,108 +53,13 @@ ...@@ -60,108 +53,13 @@
#define MRDMODE 0x71 #define MRDMODE 0x71
#define MRDMODE_INTR_CH0 0x04 #define MRDMODE_INTR_CH0 0x04
#define MRDMODE_INTR_CH1 0x08 #define MRDMODE_INTR_CH1 0x08
#define MRDMODE_BLK_CH0 0x10
#define MRDMODE_BLK_CH1 0x20
#define BMIDESR0 0x72
#define UDIDETCR0 0x73 #define UDIDETCR0 0x73
#define DTPR0 0x74 #define DTPR0 0x74
#define BMIDECR1 0x78 #define BMIDECR1 0x78
#define BMIDECSR 0x79 #define BMIDECSR 0x79
#define BMIDESR1 0x7A
#define UDIDETCR1 0x7B #define UDIDETCR1 0x7B
#define DTPR1 0x7C #define DTPR1 0x7C
#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
static u8 cmd64x_proc = 0;
#define CMD_MAX_DEVS 5
static struct pci_dev *cmd_devs[CMD_MAX_DEVS];
static int n_cmd_devs;
static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index)
{
char *p = buf;
u8 reg72 = 0, reg73 = 0; /* primary */
u8 reg7a = 0, reg7b = 0; /* secondary */
u8 reg50 = 1, reg51 = 1, reg57 = 0, reg71 = 0; /* extra */
p += sprintf(p, "\nController: %d\n", index);
p += sprintf(p, "PCI-%x Chipset.\n", dev->device);
(void) pci_read_config_byte(dev, CFR, &reg50);
(void) pci_read_config_byte(dev, CNTRL, &reg51);
(void) pci_read_config_byte(dev, ARTTIM23, &reg57);
(void) pci_read_config_byte(dev, MRDMODE, &reg71);
(void) pci_read_config_byte(dev, BMIDESR0, &reg72);
(void) pci_read_config_byte(dev, UDIDETCR0, &reg73);
(void) pci_read_config_byte(dev, BMIDESR1, &reg7a);
(void) pci_read_config_byte(dev, UDIDETCR1, &reg7b);
/* PCI0643/6 originally didn't have the primary channel enable bit */
if ((dev->device == PCI_DEVICE_ID_CMD_643) ||
(dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 3))
reg51 |= CNTRL_ENA_1ST;
p += sprintf(p, "---------------- Primary Channel "
"---------------- Secondary Channel ------------\n");
p += sprintf(p, " %s %s\n",
(reg51 & CNTRL_ENA_1ST) ? "enabled " : "disabled",
(reg51 & CNTRL_ENA_2ND) ? "enabled " : "disabled");
p += sprintf(p, "---------------- drive0 --------- drive1 "
"-------- drive0 --------- drive1 ------\n");
p += sprintf(p, "DMA enabled: %s %s"
" %s %s\n",
(reg72 & 0x20) ? "yes" : "no ", (reg72 & 0x40) ? "yes" : "no ",
(reg7a & 0x20) ? "yes" : "no ", (reg7a & 0x40) ? "yes" : "no ");
p += sprintf(p, "UltraDMA mode: %s (%c) %s (%c)",
( reg73 & 0x01) ? " on" : "off",
((reg73 & 0x30) == 0x30) ? ((reg73 & 0x04) ? '3' : '0') :
((reg73 & 0x30) == 0x20) ? ((reg73 & 0x04) ? '3' : '1') :
((reg73 & 0x30) == 0x10) ? ((reg73 & 0x04) ? '4' : '2') :
((reg73 & 0x30) == 0x00) ? ((reg73 & 0x04) ? '5' : '2') : '?',
( reg73 & 0x02) ? " on" : "off",
((reg73 & 0xC0) == 0xC0) ? ((reg73 & 0x08) ? '3' : '0') :
((reg73 & 0xC0) == 0x80) ? ((reg73 & 0x08) ? '3' : '1') :
((reg73 & 0xC0) == 0x40) ? ((reg73 & 0x08) ? '4' : '2') :
((reg73 & 0xC0) == 0x00) ? ((reg73 & 0x08) ? '5' : '2') : '?');
p += sprintf(p, " %s (%c) %s (%c)\n",
( reg7b & 0x01) ? " on" : "off",
((reg7b & 0x30) == 0x30) ? ((reg7b & 0x04) ? '3' : '0') :
((reg7b & 0x30) == 0x20) ? ((reg7b & 0x04) ? '3' : '1') :
((reg7b & 0x30) == 0x10) ? ((reg7b & 0x04) ? '4' : '2') :
((reg7b & 0x30) == 0x00) ? ((reg7b & 0x04) ? '5' : '2') : '?',
( reg7b & 0x02) ? " on" : "off",
((reg7b & 0xC0) == 0xC0) ? ((reg7b & 0x08) ? '3' : '0') :
((reg7b & 0xC0) == 0x80) ? ((reg7b & 0x08) ? '3' : '1') :
((reg7b & 0xC0) == 0x40) ? ((reg7b & 0x08) ? '4' : '2') :
((reg7b & 0xC0) == 0x00) ? ((reg7b & 0x08) ? '5' : '2') : '?');
p += sprintf(p, "Interrupt: %s, %s %s, %s\n",
(reg71 & MRDMODE_BLK_CH0 ) ? "blocked" : "enabled",
(reg50 & CFR_INTR_CH0 ) ? "pending" : "clear ",
(reg71 & MRDMODE_BLK_CH1 ) ? "blocked" : "enabled",
(reg57 & ARTTIM23_INTR_CH1) ? "pending" : "clear ");
return (char *)p;
}
static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
{
char *p = buffer;
int i;
for (i = 0; i < n_cmd_devs; i++) {
struct pci_dev *dev = cmd_devs[i];
p = print_cmd64x_get_info(p, dev, i);
}
return p-buffer; /* => must be less than 4k! */
}
#endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */
static u8 quantize_timing(int timing, int quant) static u8 quantize_timing(int timing, int quant)
{ {
return (timing + quant - 1) / quant; return (timing + quant - 1) / quant;
...@@ -472,16 +370,6 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha ...@@ -472,16 +370,6 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
mrdmode &= ~0x30; mrdmode &= ~0x30;
(void) pci_write_config_byte(dev, MRDMODE, (mrdmode | 0x02)); (void) pci_write_config_byte(dev, MRDMODE, (mrdmode | 0x02));
#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
cmd_devs[n_cmd_devs++] = dev;
if (!cmd64x_proc) {
cmd64x_proc = 1;
ide_pci_create_host_proc("cmd64x", cmd64x_get_info);
}
#endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_IDE_PROC_FS */
return 0; return 0;
} }
......
...@@ -71,7 +71,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio) ...@@ -71,7 +71,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *pdev = hwif->pci_dev; struct pci_dev *pdev = hwif->pci_dev;
int controller = drive->dn > 1 ? 1 : 0; int controller = drive->dn > 1 ? 1 : 0;
u8 reg;
/* FIXME: if DMA = 1 do we need to set the DMA bit here ? */ /* FIXME: if DMA = 1 do we need to set the DMA bit here ? */
...@@ -91,11 +90,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio) ...@@ -91,11 +90,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1), pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1),
(cs5520_pio_clocks[pio].recovery << 4) | (cs5520_pio_clocks[pio].recovery << 4) |
(cs5520_pio_clocks[pio].assert)); (cs5520_pio_clocks[pio].assert));
/* Set the DMA enable/disable flag */
reg = inb(hwif->dma_base + 0x02 + 8*controller);
reg |= 1<<((drive->dn&1)+5);
outb(reg, hwif->dma_base + 0x02 + 8*controller);
} }
static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed) static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
...@@ -109,13 +103,14 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed) ...@@ -109,13 +103,14 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
* We wrap the DMA activate to set the vdma flag. This is needed * We wrap the DMA activate to set the vdma flag. This is needed
* so that the IDE DMA layer issues PIO not DMA commands over the * so that the IDE DMA layer issues PIO not DMA commands over the
* DMA channel * DMA channel
*
* ATAPI is harder so disable it for now using IDE_HFLAG_NO_ATAPI_DMA
*/ */
static int cs5520_dma_on(ide_drive_t *drive) static void cs5520_dma_host_set(ide_drive_t *drive, int on)
{ {
/* ATAPI is harder so leave it for now */ drive->vdma = on;
drive->vdma = 1; ide_dma_host_set(drive, on);
return 0;
} }
static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
...@@ -126,7 +121,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) ...@@ -126,7 +121,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
if (hwif->dma_base == 0) if (hwif->dma_base == 0)
return; return;
hwif->ide_dma_on = &cs5520_dma_on; hwif->dma_host_set = &cs5520_dma_host_set;
} }
#define DECLARE_CS_DEV(name_str) \ #define DECLARE_CS_DEV(name_str) \
......
/* /*
* linux/drivers/ide/pci/cy82c693.c Version 0.42 Oct 23, 2007 * linux/drivers/ide/pci/cy82c693.c Version 0.44 Nov 8, 2007
* *
* Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer * Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
...@@ -176,17 +176,12 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk) ...@@ -176,17 +176,12 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
* set DMA mode a specific channel for CY82C693 * set DMA mode a specific channel for CY82C693
*/ */
static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
{ {
u8 index = 0, data = 0; ide_hwif_t *hwif = drive->hwif;
u8 single = (mode & 0x10) >> 4, index = 0, data = 0;
if (mode>2) /* make sure we set a valid mode */ index = hwif->channel ? CY82_INDEX_CHANNEL1 : CY82_INDEX_CHANNEL0;
mode = 2;
if (mode > drive->id->tDMA) /* to be absolutly sure we have a valid mode */
mode = drive->id->tDMA;
index = (HWIF(drive)->channel==0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1;
#if CY82C693_DEBUG_LOGS #if CY82C693_DEBUG_LOGS
/* for debug let's show the previous values */ /* for debug let's show the previous values */
...@@ -199,7 +194,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) ...@@ -199,7 +194,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
(data&0x3), ((data>>2)&1)); (data&0x3), ((data>>2)&1));
#endif /* CY82C693_DEBUG_LOGS */ #endif /* CY82C693_DEBUG_LOGS */
data = (u8)mode|(u8)(single<<2); data = (mode & 3) | (single << 2);
outb(index, CY82_INDEX_PORT); outb(index, CY82_INDEX_PORT);
outb(data, CY82_DATA_PORT); outb(data, CY82_DATA_PORT);
...@@ -207,7 +202,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) ...@@ -207,7 +202,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
#if CY82C693_DEBUG_INFO #if CY82C693_DEBUG_INFO
printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n",
drive->name, HWIF(drive)->channel, drive->select.b.unit, drive->name, HWIF(drive)->channel, drive->select.b.unit,
mode, single); mode & 3, single);
#endif /* CY82C693_DEBUG_INFO */ #endif /* CY82C693_DEBUG_INFO */
/* /*
...@@ -230,39 +225,6 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) ...@@ -230,39 +225,6 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
#endif /* CY82C693_DEBUG_INFO */ #endif /* CY82C693_DEBUG_INFO */
} }
/*
* used to set DMA mode for CY82C693 (single and multi modes)
*/
static int cy82c693_ide_dma_on (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
#if CY82C693_DEBUG_INFO
printk (KERN_INFO "dma_on: %s\n", drive->name);
#endif /* CY82C693_DEBUG_INFO */
if (id != NULL) {
/* Enable DMA on any drive that has DMA
* (multi or single) enabled
*/
if (id->field_valid & 2) { /* regular DMA */
int mmode, smode;
mmode = id->dma_mword & (id->dma_mword >> 8);
smode = id->dma_1word & (id->dma_1word >> 8);
if (mmode != 0) {
/* enable multi */
cy82c693_dma_enable(drive, (mmode >> 1), 0);
} else if (smode != 0) {
/* enable single */
cy82c693_dma_enable(drive, (smode >> 1), 1);
}
}
}
return __ide_dma_on(drive);
}
static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
...@@ -429,11 +391,7 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c ...@@ -429,11 +391,7 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c
static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif) static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
{ {
hwif->set_pio_mode = &cy82c693_set_pio_mode; hwif->set_pio_mode = &cy82c693_set_pio_mode;
hwif->set_dma_mode = &cy82c693_set_dma_mode;
if (hwif->dma_base == 0)
return;
hwif->ide_dma_on = &cy82c693_ide_dma_on;
} }
static void __devinit init_iops_cy82c693(ide_hwif_t *hwif) static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
...@@ -454,11 +412,11 @@ static const struct ide_port_info cy82c693_chipset __devinitdata = { ...@@ -454,11 +412,11 @@ static const struct ide_port_info cy82c693_chipset __devinitdata = {
.init_iops = init_iops_cy82c693, .init_iops = init_iops_cy82c693,
.init_hwif = init_hwif_cy82c693, .init_hwif = init_hwif_cy82c693,
.chipset = ide_cy82c693, .chipset = ide_cy82c693,
.host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_CY82C693 |
IDE_HFLAG_BOOTABLE, IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.swdma_mask = ATA_SWDMA2_ONLY, .swdma_mask = ATA_SWDMA2,
.mwdma_mask = ATA_MWDMA2_ONLY, .mwdma_mask = ATA_MWDMA2,
}; };
static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id) static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
......
...@@ -80,7 +80,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) ...@@ -80,7 +80,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
hw.irq = dev->irq; hw.irq = dev->irq;
hw.chipset = ide_pci; /* this enables IRQ sharing */ hw.chipset = ide_pci; /* this enables IRQ sharing */
rc = ide_register_hw(&hw, &ide_undecoded_slave, 0, &hwif); rc = ide_register_hw(&hw, &ide_undecoded_slave, &hwif);
if (rc < 0) { if (rc < 0) {
printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc); printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc);
pci_disable_device(dev); pci_disable_device(dev);
......
...@@ -725,15 +725,18 @@ static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio) ...@@ -725,15 +725,18 @@ static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
hpt3xx_set_mode(drive, XFER_PIO_0 + pio); hpt3xx_set_mode(drive, XFER_PIO_0 + pio);
} }
static int hpt3xx_quirkproc(ide_drive_t *drive) static void hpt3xx_quirkproc(ide_drive_t *drive)
{ {
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
const char **list = quirk_drives; const char **list = quirk_drives;
while (*list) while (*list)
if (strstr(id->model, *list++)) if (strstr(id->model, *list++)) {
return 1; drive->quirk_list = 1;
return 0; return;
}
drive->quirk_list = 0;
} }
static void hpt3xx_maskproc(ide_drive_t *drive, int mask) static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
......
...@@ -431,33 +431,29 @@ static u8 __devinit ata66_it821x(ide_hwif_t *hwif) ...@@ -431,33 +431,29 @@ static u8 __devinit ata66_it821x(ide_hwif_t *hwif)
} }
/** /**
* it821x_fixup - post init callback * it821x_quirkproc - post init callback
* @hwif: interface * @drive: drive
* *
* This callback is run after the drives have been probed but * This callback is run after the drive has been probed but
* before anything gets attached. It allows drivers to do any * before anything gets attached. It allows drivers to do any
* final tuning that is needed, or fixups to work around bugs. * final tuning that is needed, or fixups to work around bugs.
*/ */
static void __devinit it821x_fixups(ide_hwif_t *hwif) static void __devinit it821x_quirkproc(ide_drive_t *drive)
{ {
struct it821x_dev *itdev = ide_get_hwifdata(hwif); struct it821x_dev *itdev = ide_get_hwifdata(drive->hwif);
int i; struct hd_driveid *id = drive->id;
u16 *idbits = (u16 *)drive->id;
if(!itdev->smart) { if (!itdev->smart) {
/* /*
* If we are in pass through mode then not much * If we are in pass through mode then not much
* needs to be done, but we do bother to clear the * needs to be done, but we do bother to clear the
* IRQ mask as we may well be in PIO (eg rev 0x10) * IRQ mask as we may well be in PIO (eg rev 0x10)
* for now and we know unmasking is safe on this chipset. * for now and we know unmasking is safe on this chipset.
*/ */
for (i = 0; i < 2; i++) { drive->unmask = 1;
ide_drive_t *drive = &hwif->drives[i]; } else {
if(drive->present)
drive->unmask = 1;
}
return;
}
/* /*
* Perform fixups on smart mode. We need to "lose" some * Perform fixups on smart mode. We need to "lose" some
* capabilities the firmware lacks but does not filter, and * capabilities the firmware lacks but does not filter, and
...@@ -465,16 +461,6 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif) ...@@ -465,16 +461,6 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
* in RAID mode. * in RAID mode.
*/ */
for(i = 0; i < 2; i++) {
ide_drive_t *drive = &hwif->drives[i];
struct hd_driveid *id;
u16 *idbits;
if(!drive->present)
continue;
id = drive->id;
idbits = (u16 *)drive->id;
/* Check for RAID v native */ /* Check for RAID v native */
if(strstr(id->model, "Integrated Technology Express")) { if(strstr(id->model, "Integrated Technology Express")) {
/* In raid mode the ident block is slightly buggy /* In raid mode the ident block is slightly buggy
...@@ -537,6 +523,8 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) ...@@ -537,6 +523,8 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL); struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL);
u8 conf; u8 conf;
hwif->quirkproc = &it821x_quirkproc;
if (idev == NULL) { if (idev == NULL) {
printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n"); printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
return; return;
...@@ -633,7 +621,6 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha ...@@ -633,7 +621,6 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha
.name = name_str, \ .name = name_str, \
.init_chipset = init_chipset_it821x, \ .init_chipset = init_chipset_it821x, \
.init_hwif = init_hwif_it821x, \ .init_hwif = init_hwif_it821x, \
.fixup = it821x_fixups, \
.host_flags = IDE_HFLAG_BOOTABLE, \ .host_flags = IDE_HFLAG_BOOTABLE, \
.pio_mask = ATA_PIO4, \ .pio_mask = ATA_PIO4, \
} }
......
...@@ -203,14 +203,17 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif) ...@@ -203,14 +203,17 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA80; return ATA_CBL_PATA80;
} }
static int pdcnew_quirkproc(ide_drive_t *drive) static void pdcnew_quirkproc(ide_drive_t *drive)
{ {
const char **list, *model = drive->id->model; const char **list, *model = drive->id->model;
for (list = pdc_quirk_drives; *list != NULL; list++) for (list = pdc_quirk_drives; *list != NULL; list++)
if (strstr(model, *list) != NULL) if (strstr(model, *list) != NULL) {
return 2; drive->quirk_list = 2;
return 0; return;
}
drive->quirk_list = 0;
} }
static void pdcnew_reset(ide_drive_t *drive) static void pdcnew_reset(ide_drive_t *drive)
......
...@@ -176,14 +176,17 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif) ...@@ -176,14 +176,17 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
} }
static int pdc202xx_quirkproc (ide_drive_t *drive) static void pdc202xx_quirkproc(ide_drive_t *drive)
{ {
const char **list, *model = drive->id->model; const char **list, *model = drive->id->model;
for (list = pdc_quirk_drives; *list != NULL; list++) for (list = pdc_quirk_drives; *list != NULL; list++)
if (strstr(model, *list) != NULL) if (strstr(model, *list) != NULL) {
return 2; drive->quirk_list = 2;
return 0; return;
}
drive->quirk_list = 0;
} }
static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
......
...@@ -220,9 +220,9 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio) ...@@ -220,9 +220,9 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
} }
if (mode != -1) { if (mode != -1) {
printk("SC1200: %s: changing (U)DMA mode\n", drive->name); printk("SC1200: %s: changing (U)DMA mode\n", drive->name);
hwif->dma_off_quietly(drive); ide_dma_off_quietly(drive);
if (ide_set_dma_mode(drive, mode) == 0) if (ide_set_dma_mode(drive, mode) == 0 && drive->using_dma)
hwif->dma_host_on(drive); hwif->dma_host_set(drive, 1);
return; return;
} }
......
...@@ -164,25 +164,12 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed) ...@@ -164,25 +164,12 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
ultra_timing &= ~(0x0F << (4*unit)); ultra_timing &= ~(0x0F << (4*unit));
ultra_enable &= ~(0x01 << drive->dn); ultra_enable &= ~(0x01 << drive->dn);
switch(speed) { if (speed >= XFER_UDMA_0) {
case XFER_MW_DMA_2: dma_timing |= dma_modes[2];
case XFER_MW_DMA_1: ultra_timing |= (udma_modes[speed - XFER_UDMA_0] << (4 * unit));
case XFER_MW_DMA_0: ultra_enable |= (0x01 << drive->dn);
dma_timing |= dma_modes[speed - XFER_MW_DMA_0]; } else if (speed >= XFER_MW_DMA_0)
break; dma_timing |= dma_modes[speed - XFER_MW_DMA_0];
case XFER_UDMA_5:
case XFER_UDMA_4:
case XFER_UDMA_3:
case XFER_UDMA_2:
case XFER_UDMA_1:
case XFER_UDMA_0:
dma_timing |= dma_modes[2];
ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit));
ultra_enable |= (0x01 << drive->dn);
default:
break;
}
pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing); pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing);
pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing); pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing);
......
...@@ -277,21 +277,6 @@ sgiioc4_ide_dma_end(ide_drive_t * drive) ...@@ -277,21 +277,6 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
return dma_stat; return dma_stat;
} }
static int
sgiioc4_ide_dma_on(ide_drive_t * drive)
{
drive->using_dma = 1;
return 0;
}
static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
{
drive->using_dma = 0;
drive->hwif->dma_host_off(drive);
}
static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed) static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
{ {
} }
...@@ -303,13 +288,10 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * drive) ...@@ -303,13 +288,10 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
return sgiioc4_checkirq(HWIF(drive)); return sgiioc4_checkirq(HWIF(drive));
} }
static void sgiioc4_dma_host_on(ide_drive_t * drive) static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
{
}
static void sgiioc4_dma_host_off(ide_drive_t * drive)
{ {
sgiioc4_clearirq(drive); if (!on)
sgiioc4_clearirq(drive);
} }
static void static void
...@@ -593,14 +575,11 @@ ide_init_sgiioc4(ide_hwif_t * hwif) ...@@ -593,14 +575,11 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
hwif->mwdma_mask = ATA_MWDMA2_ONLY; hwif->mwdma_mask = ATA_MWDMA2_ONLY;
hwif->dma_host_set = &sgiioc4_dma_host_set;
hwif->dma_setup = &sgiioc4_ide_dma_setup; hwif->dma_setup = &sgiioc4_ide_dma_setup;
hwif->dma_start = &sgiioc4_ide_dma_start; hwif->dma_start = &sgiioc4_ide_dma_start;
hwif->ide_dma_end = &sgiioc4_ide_dma_end; hwif->ide_dma_end = &sgiioc4_ide_dma_end;
hwif->ide_dma_on = &sgiioc4_ide_dma_on;
hwif->dma_off_quietly = &sgiioc4_dma_off_quietly;
hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq; hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
hwif->dma_host_on = &sgiioc4_dma_host_on;
hwif->dma_host_off = &sgiioc4_dma_host_off;
hwif->dma_lost_irq = &sgiioc4_dma_lost_irq; hwif->dma_lost_irq = &sgiioc4_dma_lost_irq;
hwif->dma_timeout = &ide_dma_timeout; hwif->dma_timeout = &ide_dma_timeout;
} }
...@@ -614,6 +593,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) ...@@ -614,6 +593,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
ide_hwif_t *hwif; ide_hwif_t *hwif;
int h; int h;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
hw_regs_t hw;
/* /*
* Find an empty HWIF; if none available, return -ENOMEM. * Find an empty HWIF; if none available, return -ENOMEM.
...@@ -653,21 +633,16 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) ...@@ -653,21 +633,16 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
return -ENOMEM; return -ENOMEM;
} }
if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) { /* Initialize the IO registers */
hw_regs_t hw; memset(&hw, 0, sizeof(hw));
sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
/* Initialize the IO registers */ hw.irq = dev->irq;
memset(&hw, 0, sizeof(hw)); hw.chipset = ide_pci;
sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport); hw.dev = &dev->dev;
memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports)); ide_init_port_hw(hwif, &hw);
hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
}
hwif->irq = dev->irq;
hwif->chipset = ide_pci;
hwif->pci_dev = dev; hwif->pci_dev = dev;
hwif->channel = 0; /* Single Channel chip */ hwif->channel = 0; /* Single Channel chip */
hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */
/* The IOC4 uses MMIO rather than Port IO. */ /* The IOC4 uses MMIO rather than Port IO. */
default_hwif_mmiops(hwif); default_hwif_mmiops(hwif);
......
...@@ -713,9 +713,6 @@ static int is_dev_seagate_sata(ide_drive_t *drive) ...@@ -713,9 +713,6 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
const char *s = &drive->id->model[0]; const char *s = &drive->id->model[0];
unsigned len; unsigned len;
if (!drive->present)
return 0;
len = strnlen(s, sizeof(drive->id->model)); len = strnlen(s, sizeof(drive->id->model));
if ((len > 4) && (!memcmp(s, "ST", 2))) { if ((len > 4) && (!memcmp(s, "ST", 2))) {
...@@ -730,18 +727,20 @@ static int is_dev_seagate_sata(ide_drive_t *drive) ...@@ -730,18 +727,20 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
} }
/** /**
* siimage_fixup - post probe fixups * sil_quirkproc - post probe fixups
* @hwif: interface to fix up * @drive: drive
* *
* Called after drive probe we use this to decide whether the * Called after drive probe we use this to decide whether the
* Seagate fixup must be applied. This used to be in init_iops but * Seagate fixup must be applied. This used to be in init_iops but
* that can occur before we know what drives are present. * that can occur before we know what drives are present.
*/ */
static void __devinit siimage_fixup(ide_hwif_t *hwif) static void __devinit sil_quirkproc(ide_drive_t *drive)
{ {
ide_hwif_t *hwif = drive->hwif;
/* Try and raise the rqsize */ /* Try and raise the rqsize */
if (!is_sata(hwif) || !is_dev_seagate_sata(&hwif->drives[0])) if (!is_sata(hwif) || !is_dev_seagate_sata(drive))
hwif->rqsize = 128; hwif->rqsize = 128;
} }
...@@ -804,6 +803,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) ...@@ -804,6 +803,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
hwif->set_pio_mode = &sil_set_pio_mode; hwif->set_pio_mode = &sil_set_pio_mode;
hwif->set_dma_mode = &sil_set_dma_mode; hwif->set_dma_mode = &sil_set_dma_mode;
hwif->quirkproc = &sil_quirkproc;
if (sata) { if (sata) {
static int first = 1; static int first = 1;
...@@ -842,7 +842,6 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) ...@@ -842,7 +842,6 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
.init_chipset = init_chipset_siimage, \ .init_chipset = init_chipset_siimage, \
.init_iops = init_iops_siimage, \ .init_iops = init_iops_siimage, \
.init_hwif = init_hwif_siimage, \ .init_hwif = init_hwif_siimage, \
.fixup = siimage_fixup, \
.host_flags = IDE_HFLAG_BOOTABLE, \ .host_flags = IDE_HFLAG_BOOTABLE, \
.pio_mask = ATA_PIO4, \ .pio_mask = ATA_PIO4, \
.mwdma_mask = ATA_MWDMA2, \ .mwdma_mask = ATA_MWDMA2, \
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org
* *
* Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com>
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz
*/ */
#include <linux/types.h> #include <linux/types.h>
...@@ -90,14 +91,8 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio) ...@@ -90,14 +91,8 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
drive->drive_data &= 0xffff0000; drive->drive_data &= 0xffff0000;
drive->drive_data |= drv_ctrl; drive->drive_data |= drv_ctrl;
if (!drive->using_dma) { pci_write_config_word(dev, reg, drv_ctrl);
/* pci_read_config_word (dev, reg, &drv_ctrl);
* If we are actually using MW DMA, then we can not
* reprogram the interface drive control register.
*/
pci_write_config_word(dev, reg, drv_ctrl);
pci_read_config_word (dev, reg, &drv_ctrl);
}
printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name, printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name,
ide_xfer_verbose(pio + XFER_PIO_0), ide_xfer_verbose(pio + XFER_PIO_0),
...@@ -123,17 +118,6 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed) ...@@ -123,17 +118,6 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
*/ */
drive->drive_data &= 0x0000ffff; drive->drive_data &= 0x0000ffff;
drive->drive_data |= (unsigned long)drv_ctrl << 16; drive->drive_data |= (unsigned long)drv_ctrl << 16;
/*
* If we are already using DMA, we just reprogram
* the drive control register.
*/
if (drive->using_dma) {
struct pci_dev *dev = HWIF(drive)->pci_dev;
int reg = 0x44 + drive->dn * 4;
pci_write_config_word(dev, reg, drv_ctrl);
}
} }
/* /*
...@@ -201,6 +185,11 @@ static void sl82c105_dma_start(ide_drive_t *drive) ...@@ -201,6 +185,11 @@ static void sl82c105_dma_start(ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
int reg = 0x44 + drive->dn * 4;
DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name));
pci_write_config_word(dev, reg, drive->drive_data >> 16);
sl82c105_reset_host(dev); sl82c105_reset_host(dev);
ide_dma_start(drive); ide_dma_start(drive);
...@@ -214,64 +203,24 @@ static void sl82c105_dma_timeout(ide_drive_t *drive) ...@@ -214,64 +203,24 @@ static void sl82c105_dma_timeout(ide_drive_t *drive)
ide_dma_timeout(drive); ide_dma_timeout(drive);
} }
static int sl82c105_ide_dma_on(ide_drive_t *drive) static int sl82c105_dma_end(ide_drive_t *drive)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
int rc, reg = 0x44 + drive->dn * 4;
DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name));
rc = __ide_dma_on(drive);
if (rc == 0) {
pci_write_config_word(dev, reg, drive->drive_data >> 16);
printk(KERN_INFO "%s: DMA enabled\n", drive->name);
}
return rc;
}
static void sl82c105_dma_off_quietly(ide_drive_t *drive)
{ {
struct pci_dev *dev = HWIF(drive)->pci_dev; struct pci_dev *dev = HWIF(drive)->pci_dev;
int reg = 0x44 + drive->dn * 4; int reg = 0x44 + drive->dn * 4;
int ret;
DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name)); DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name));
pci_write_config_word(dev, reg, drive->drive_data); ret = __ide_dma_end(drive);
ide_dma_off_quietly(drive); pci_write_config_word(dev, reg, drive->drive_data);
}
/* return ret;
* Ok, that is nasty, but we must make sure the DMA timings
* won't be used for a PIO access. The solution here is
* to make sure the 16 bits mode is diabled on the channel
* when DMA is enabled, thus causing the chip to use PIO0
* timings for those operations.
*/
static void sl82c105_selectproc(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u32 val, old, mask;
//DBG(("sl82c105_selectproc(drive:%s)\n", drive->name));
mask = hwif->channel ? CTRL_P1F16 : CTRL_P0F16;
old = val = (u32)pci_get_drvdata(dev);
if (drive->using_dma)
val &= ~mask;
else
val |= mask;
if (old != val) {
pci_write_config_dword(dev, 0x40, val);
pci_set_drvdata(dev, (void *)val);
}
} }
/* /*
* ATA reset will clear the 16 bits mode in the control * ATA reset will clear the 16 bits mode in the control
* register, we need to update our cache * register, we need to reprogram it
*/ */
static void sl82c105_resetproc(ide_drive_t *drive) static void sl82c105_resetproc(ide_drive_t *drive)
{ {
...@@ -281,7 +230,8 @@ static void sl82c105_resetproc(ide_drive_t *drive) ...@@ -281,7 +230,8 @@ static void sl82c105_resetproc(ide_drive_t *drive)
DBG(("sl82c105_resetproc(drive:%s)\n", drive->name)); DBG(("sl82c105_resetproc(drive:%s)\n", drive->name));
pci_read_config_dword(dev, 0x40, &val); pci_read_config_dword(dev, 0x40, &val);
pci_set_drvdata(dev, (void *)val); val |= (CTRL_P1F16 | CTRL_P0F16);
pci_write_config_dword(dev, 0x40, val);
} }
/* /*
...@@ -334,7 +284,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c ...@@ -334,7 +284,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
pci_read_config_dword(dev, 0x40, &val); pci_read_config_dword(dev, 0x40, &val);
val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
pci_write_config_dword(dev, 0x40, val); pci_write_config_dword(dev, 0x40, val);
pci_set_drvdata(dev, (void *)val);
return dev->irq; return dev->irq;
} }
...@@ -350,7 +299,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) ...@@ -350,7 +299,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
hwif->set_pio_mode = &sl82c105_set_pio_mode; hwif->set_pio_mode = &sl82c105_set_pio_mode;
hwif->set_dma_mode = &sl82c105_set_dma_mode; hwif->set_dma_mode = &sl82c105_set_dma_mode;
hwif->selectproc = &sl82c105_selectproc;
hwif->resetproc = &sl82c105_resetproc; hwif->resetproc = &sl82c105_resetproc;
if (!hwif->dma_base) if (!hwif->dma_base)
...@@ -369,10 +317,9 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) ...@@ -369,10 +317,9 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
hwif->mwdma_mask = ATA_MWDMA2; hwif->mwdma_mask = ATA_MWDMA2;
hwif->ide_dma_on = &sl82c105_ide_dma_on;
hwif->dma_off_quietly = &sl82c105_dma_off_quietly;
hwif->dma_lost_irq = &sl82c105_dma_lost_irq; hwif->dma_lost_irq = &sl82c105_dma_lost_irq;
hwif->dma_start = &sl82c105_dma_start; hwif->dma_start = &sl82c105_dma_start;
hwif->ide_dma_end = &sl82c105_dma_end;
hwif->dma_timeout = &sl82c105_dma_timeout; hwif->dma_timeout = &sl82c105_dma_timeout;
if (hwif->mate) if (hwif->mate)
......
...@@ -241,11 +241,7 @@ static int trm290_ide_dma_test_irq (ide_drive_t *drive) ...@@ -241,11 +241,7 @@ static int trm290_ide_dma_test_irq (ide_drive_t *drive)
return (status == 0x00ff); return (status == 0x00ff);
} }
static void trm290_dma_host_on(ide_drive_t *drive) static void trm290_dma_host_set(ide_drive_t *drive, int on)
{
}
static void trm290_dma_host_off(ide_drive_t *drive)
{ {
} }
...@@ -289,8 +285,7 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif) ...@@ -289,8 +285,7 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3); ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
hwif->dma_host_off = &trm290_dma_host_off; hwif->dma_host_set = &trm290_dma_host_set;
hwif->dma_host_on = &trm290_dma_host_on;
hwif->dma_setup = &trm290_dma_setup; hwif->dma_setup = &trm290_dma_setup;
hwif->dma_exec_cmd = &trm290_dma_exec_cmd; hwif->dma_exec_cmd = &trm290_dma_exec_cmd;
hwif->dma_start = &trm290_dma_start; hwif->dma_start = &trm290_dma_start;
......
obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o
obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += mpc8xx.o
...@@ -838,3 +838,21 @@ void m8xx_ide_init(void) ...@@ -838,3 +838,21 @@ void m8xx_ide_init(void)
ppc_ide_md.default_io_base = m8xx_ide_default_io_base; ppc_ide_md.default_io_base = m8xx_ide_default_io_base;
ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports;
} }
static int __init mpc8xx_ide_probe(void)
{
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
#ifdef IDE0_BASE_OFFSET
idx[0] = 0;
#ifdef IDE1_BASE_OFFSET
idx[1] = 1;
#endif
#endif
ide_device_add(idx);
return 0;
}
module_init(mpc8xx_ide_probe);
...@@ -1012,12 +1012,11 @@ pmac_ide_do_resume(ide_hwif_t *hwif) ...@@ -1012,12 +1012,11 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
* rare machines unfortunately, but it's better this way. * rare machines unfortunately, but it's better this way.
*/ */
static int static int
pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
{ {
struct device_node *np = pmif->node; struct device_node *np = pmif->node;
const int *bidp; const int *bidp;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
hw_regs_t hw;
pmif->cable_80 = 0; pmif->cable_80 = 0;
pmif->broken_dma = pmif->broken_dma_warn = 0; pmif->broken_dma = pmif->broken_dma_warn = 0;
...@@ -1103,11 +1102,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) ...@@ -1103,11 +1102,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
/* Tell common code _not_ to mess with resources */ /* Tell common code _not_ to mess with resources */
hwif->mmio = 1; hwif->mmio = 1;
hwif->hwif_data = pmif; hwif->hwif_data = pmif;
memset(&hw, 0, sizeof(hw)); hw->chipset = ide_pmac;
pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, &hwif->irq); ide_init_port_hw(hwif, hw);
memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports)); hwif->noprobe = pmif->mediabay;
hwif->chipset = ide_pmac;
hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay;
hwif->hold = pmif->mediabay; hwif->hold = pmif->mediabay;
hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
hwif->drives[0].unmask = 1; hwif->drives[0].unmask = 1;
...@@ -1136,8 +1133,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) ...@@ -1136,8 +1133,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
hwif->noprobe = 0; hwif->noprobe = 0;
#endif /* CONFIG_PMAC_MEDIABAY */ #endif /* CONFIG_PMAC_MEDIABAY */
hwif->sg_max_nents = MAX_DCMDS;
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
/* has a DBDMA controller channel */ /* has a DBDMA controller channel */
if (pmif->dma_regs) if (pmif->dma_regs)
...@@ -1163,6 +1158,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) ...@@ -1163,6 +1158,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
ide_hwif_t *hwif; ide_hwif_t *hwif;
pmac_ide_hwif_t *pmif; pmac_ide_hwif_t *pmif;
int i, rc; int i, rc;
hw_regs_t hw;
i = 0; i = 0;
while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0 while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0
...@@ -1205,7 +1201,6 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) ...@@ -1205,7 +1201,6 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
regbase = (unsigned long) base; regbase = (unsigned long) base;
hwif->pci_dev = mdev->bus->pdev; hwif->pci_dev = mdev->bus->pdev;
hwif->gendev.parent = &mdev->ofdev.dev;
pmif->mdev = mdev; pmif->mdev = mdev;
pmif->node = mdev->ofdev.node; pmif->node = mdev->ofdev.node;
...@@ -1223,7 +1218,12 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) ...@@ -1223,7 +1218,12 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
dev_set_drvdata(&mdev->ofdev.dev, hwif); dev_set_drvdata(&mdev->ofdev.dev, hwif);
rc = pmac_ide_setup_device(pmif, hwif); memset(&hw, 0, sizeof(hw));
pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, NULL);
hw.irq = irq;
hw.dev = &mdev->ofdev.dev;
rc = pmac_ide_setup_device(pmif, hwif, &hw);
if (rc != 0) { if (rc != 0) {
/* The inteface is released to the common IDE layer */ /* The inteface is released to the common IDE layer */
dev_set_drvdata(&mdev->ofdev.dev, NULL); dev_set_drvdata(&mdev->ofdev.dev, NULL);
...@@ -1282,6 +1282,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1282,6 +1282,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
void __iomem *base; void __iomem *base;
unsigned long rbase, rlen; unsigned long rbase, rlen;
int i, rc; int i, rc;
hw_regs_t hw;
np = pci_device_to_OF_node(pdev); np = pci_device_to_OF_node(pdev);
if (np == NULL) { if (np == NULL) {
...@@ -1315,7 +1316,6 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1315,7 +1316,6 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
} }
hwif->pci_dev = pdev; hwif->pci_dev = pdev;
hwif->gendev.parent = &pdev->dev;
pmif->mdev = NULL; pmif->mdev = NULL;
pmif->node = np; pmif->node = np;
...@@ -1332,7 +1332,12 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1332,7 +1332,12 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_drvdata(pdev, hwif); pci_set_drvdata(pdev, hwif);
rc = pmac_ide_setup_device(pmif, hwif); memset(&hw, 0, sizeof(hw));
pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, NULL);
hw.irq = pdev->irq;
hw.dev = &pdev->dev;
rc = pmac_ide_setup_device(pmif, hwif, &hw);
if (rc != 0) { if (rc != 0) {
/* The inteface is released to the common IDE layer */ /* The inteface is released to the common IDE layer */
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
...@@ -1698,11 +1703,7 @@ pmac_ide_dma_test_irq (ide_drive_t *drive) ...@@ -1698,11 +1703,7 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
return 1; return 1;
} }
static void pmac_ide_dma_host_off(ide_drive_t *drive) static void pmac_ide_dma_host_set(ide_drive_t *drive, int on)
{
}
static void pmac_ide_dma_host_on(ide_drive_t *drive)
{ {
} }
...@@ -1748,15 +1749,14 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) ...@@ -1748,15 +1749,14 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
return; return;
} }
hwif->dma_off_quietly = &ide_dma_off_quietly; hwif->sg_max_nents = MAX_DCMDS;
hwif->ide_dma_on = &__ide_dma_on;
hwif->dma_host_set = &pmac_ide_dma_host_set;
hwif->dma_setup = &pmac_ide_dma_setup; hwif->dma_setup = &pmac_ide_dma_setup;
hwif->dma_exec_cmd = &pmac_ide_dma_exec_cmd; hwif->dma_exec_cmd = &pmac_ide_dma_exec_cmd;
hwif->dma_start = &pmac_ide_dma_start; hwif->dma_start = &pmac_ide_dma_start;
hwif->ide_dma_end = &pmac_ide_dma_end; hwif->ide_dma_end = &pmac_ide_dma_end;
hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq; hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
hwif->dma_host_off = &pmac_ide_dma_host_off;
hwif->dma_host_on = &pmac_ide_dma_host_on;
hwif->dma_timeout = &ide_dma_timeout; hwif->dma_timeout = &ide_dma_timeout;
hwif->dma_lost_irq = &pmac_ide_dma_lost_irq; hwif->dma_lost_irq = &pmac_ide_dma_lost_irq;
...@@ -1786,3 +1786,5 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) ...@@ -1786,3 +1786,5 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
} }
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
module_init(pmac_ide_probe);
...@@ -165,13 +165,17 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_ ...@@ -165,13 +165,17 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_
dma_base = pci_resource_start(dev, baridx); dma_base = pci_resource_start(dev, baridx);
if (dma_base == 0) if (dma_base == 0) {
printk(KERN_ERR "%s: DMA base is invalid\n", d->name); printk(KERN_ERR "%s: DMA base is invalid\n", d->name);
return 0;
}
} }
if ((d->host_flags & IDE_HFLAG_CS5520) == 0 && dma_base) { if (hwif->channel)
dma_base += 8;
if ((d->host_flags & IDE_HFLAG_CS5520) == 0) {
u8 simplex_stat = 0; u8 simplex_stat = 0;
dma_base += hwif->channel ? 8 : 0;
switch(dev->device) { switch(dev->device) {
case PCI_DEVICE_ID_AL_M5219: case PCI_DEVICE_ID_AL_M5219:
...@@ -359,6 +363,8 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port ...@@ -359,6 +363,8 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port
unsigned long ctl = 0, base = 0; unsigned long ctl = 0, base = 0;
ide_hwif_t *hwif; ide_hwif_t *hwif;
u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0; u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0;
u8 oldnoprobe = 0;
struct hw_regs_s hw;
if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) { if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) {
/* Possibly we should fail if these checks report true */ /* Possibly we should fail if these checks report true */
...@@ -381,26 +387,25 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port ...@@ -381,26 +387,25 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port
} }
if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL) if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL)
return NULL; /* no room in ide_hwifs[] */ return NULL; /* no room in ide_hwifs[] */
if (hwif->io_ports[IDE_DATA_OFFSET] != base ||
hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) { memset(&hw, 0, sizeof(hw));
hw_regs_t hw; hw.irq = hwif->irq ? hwif->irq : irq;
hw.dev = &dev->dev;
memset(&hw, 0, sizeof(hw)); hw.chipset = d->chipset ? d->chipset : ide_pci;
#ifndef CONFIG_IDE_ARCH_OBSOLETE_INIT ide_std_init_ports(&hw, base, ctl | 2);
ide_std_init_ports(&hw, base, ctl | 2);
#else if (hwif->io_ports[IDE_DATA_OFFSET] == base &&
ide_init_hwif_ports(&hw, base, ctl | 2, NULL); hwif->io_ports[IDE_CONTROL_OFFSET] == (ctl | 2))
#endif oldnoprobe = hwif->noprobe;
memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; ide_init_port_hw(hwif, &hw);
}
hwif->chipset = d->chipset ? d->chipset : ide_pci; hwif->noprobe = oldnoprobe;
hwif->pci_dev = dev; hwif->pci_dev = dev;
hwif->cds = d; hwif->cds = d;
hwif->channel = port; hwif->channel = port;
if (!hwif->irq)
hwif->irq = irq;
if (mate) { if (mate) {
hwif->mate = mate; hwif->mate = mate;
mate->mate = hwif; mate->mate = hwif;
...@@ -535,12 +540,8 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int ...@@ -535,12 +540,8 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int
if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL) if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)
continue; continue;
/* setup proper ancestral information */
hwif->gendev.parent = &dev->dev;
*(idx + port) = hwif->index; *(idx + port) = hwif->index;
if (d->init_iops) if (d->init_iops)
d->init_iops(hwif); d->init_iops(hwif);
...@@ -551,8 +552,6 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int ...@@ -551,8 +552,6 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int
(d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS)) (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
hwif->irq = port ? 15 : 14; hwif->irq = port ? 15 : 14;
hwif->fixup = d->fixup;
hwif->host_flags = d->host_flags; hwif->host_flags = d->host_flags;
hwif->pio_mask = d->pio_mask; hwif->pio_mask = d->pio_mask;
...@@ -699,105 +698,3 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2, ...@@ -699,105 +698,3 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
} }
EXPORT_SYMBOL_GPL(ide_setup_pci_devices); EXPORT_SYMBOL_GPL(ide_setup_pci_devices);
#ifdef CONFIG_IDEPCI_PCIBUS_ORDER
/*
* Module interfaces
*/
static int pre_init = 1; /* Before first ordered IDE scan */
static LIST_HEAD(ide_pci_drivers);
/*
* __ide_pci_register_driver - attach IDE driver
* @driver: pci driver
* @module: owner module of the driver
*
* Registers a driver with the IDE layer. The IDE layer arranges that
* boot time setup is done in the expected device order and then
* hands the controllers off to the core PCI code to do the rest of
* the work.
*
* Returns are the same as for pci_register_driver
*/
int __ide_pci_register_driver(struct pci_driver *driver, struct module *module,
const char *mod_name)
{
if (!pre_init)
return __pci_register_driver(driver, module, mod_name);
driver->driver.owner = module;
list_add_tail(&driver->node, &ide_pci_drivers);
return 0;
}
EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
/**
* ide_scan_pcidev - find an IDE driver for a device
* @dev: PCI device to check
*
* Look for an IDE driver to handle the device we are considering.
* This is only used during boot up to get the ordering correct. After
* boot up the pci layer takes over the job.
*/
static int __init ide_scan_pcidev(struct pci_dev *dev)
{
struct list_head *l;
struct pci_driver *d;
list_for_each(l, &ide_pci_drivers) {
d = list_entry(l, struct pci_driver, node);
if (d->id_table) {
const struct pci_device_id *id =
pci_match_id(d->id_table, dev);
if (id != NULL && d->probe(dev, id) >= 0) {
dev->driver = d;
pci_dev_get(dev);
return 1;
}
}
}
return 0;
}
/**
* ide_scan_pcibus - perform the initial IDE driver scan
* @scan_direction: set for reverse order scanning
*
* Perform the initial bus rather than driver ordered scan of the
* PCI drivers. After this all IDE pci handling becomes standard
* module ordering not traditionally ordered.
*/
void __init ide_scan_pcibus (int scan_direction)
{
struct pci_dev *dev = NULL;
struct pci_driver *d;
struct list_head *l, *n;
pre_init = 0;
if (!scan_direction)
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
ide_scan_pcidev(dev);
else
while ((dev = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID,
dev)))
ide_scan_pcidev(dev);
/*
* Hand the drivers over to the PCI layer now we
* are post init.
*/
list_for_each_safe(l, n, &ide_pci_drivers) {
list_del(l);
d = list_entry(l, struct pci_driver, node);
if (__pci_register_driver(d, d->driver.owner,
d->driver.mod_name))
printk(KERN_ERR "%s: failed to register %s driver\n",
__FUNCTION__, d->driver.mod_name);
}
}
#endif
...@@ -563,7 +563,8 @@ static void media_bay_step(int i) ...@@ -563,7 +563,8 @@ static void media_bay_step(int i)
ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL); ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL);
hw.irq = bay->cd_irq; hw.irq = bay->cd_irq;
hw.chipset = ide_pmac; hw.chipset = ide_pmac;
bay->cd_index = ide_register_hw(&hw, NULL, 0, NULL); bay->cd_index =
ide_register_hw(&hw, NULL, NULL);
pmu_resume(); pmu_resume();
} }
if (bay->cd_index == -1) { if (bay->cd_index == -1) {
......
...@@ -143,7 +143,6 @@ enum rq_cmd_type_bits { ...@@ -143,7 +143,6 @@ enum rq_cmd_type_bits {
* use REQ_TYPE_SPECIAL and use rq->cmd[0] with the range of driver * use REQ_TYPE_SPECIAL and use rq->cmd[0] with the range of driver
* private REQ_LB opcodes to differentiate what type of request this is * private REQ_LB opcodes to differentiate what type of request this is
*/ */
REQ_TYPE_ATA_CMD,
REQ_TYPE_ATA_TASKFILE, REQ_TYPE_ATA_TASKFILE,
REQ_TYPE_ATA_PC, REQ_TYPE_ATA_PC,
}; };
......
...@@ -107,7 +107,6 @@ typedef unsigned char byte; /* used everywhere */ ...@@ -107,7 +107,6 @@ typedef unsigned char byte; /* used everywhere */
#define BAD_W_STAT (BAD_R_STAT | WRERR_STAT) #define BAD_W_STAT (BAD_R_STAT | WRERR_STAT)
#define BAD_STAT (BAD_R_STAT | DRQ_STAT) #define BAD_STAT (BAD_R_STAT | DRQ_STAT)
#define DRIVE_READY (READY_STAT | SEEK_STAT) #define DRIVE_READY (READY_STAT | SEEK_STAT)
#define DATA_READY (DRQ_STAT)
#define BAD_CRC (ABRT_ERR | ICRC_ERR) #define BAD_CRC (ABRT_ERR | ICRC_ERR)
...@@ -198,8 +197,11 @@ typedef struct hw_regs_s { ...@@ -198,8 +197,11 @@ typedef struct hw_regs_s {
} hw_regs_t; } hw_regs_t;
struct hwif_s * ide_find_port(unsigned long); struct hwif_s * ide_find_port(unsigned long);
void ide_init_port_data(struct hwif_s *, unsigned int);
void ide_init_port_hw(struct hwif_s *, hw_regs_t *);
int ide_register_hw(hw_regs_t *, void (*)(struct hwif_s *), int, struct ide_drive_s;
int ide_register_hw(hw_regs_t *, void (*)(struct ide_drive_s *),
struct hwif_s **); struct hwif_s **);
void ide_setup_ports( hw_regs_t *hw, void ide_setup_ports( hw_regs_t *hw,
...@@ -391,7 +393,6 @@ typedef struct ide_drive_s { ...@@ -391,7 +393,6 @@ typedef struct ide_drive_s {
u8 state; /* retry state */ u8 state; /* retry state */
u8 waiting_for_dma; /* dma currently in progress */ u8 waiting_for_dma; /* dma currently in progress */
u8 unmask; /* okay to unmask other irqs */ u8 unmask; /* okay to unmask other irqs */
u8 bswap; /* byte swap data */
u8 noflush; /* don't attempt flushes */ u8 noflush; /* don't attempt flushes */
u8 dsc_overlap; /* DSC overlap */ u8 dsc_overlap; /* DSC overlap */
u8 nice1; /* give potential excess bandwidth */ u8 nice1; /* give potential excess bandwidth */
...@@ -527,31 +528,26 @@ typedef struct hwif_s { ...@@ -527,31 +528,26 @@ typedef struct hwif_s {
/* special host masking for drive selection */ /* special host masking for drive selection */
void (*maskproc)(ide_drive_t *, int); void (*maskproc)(ide_drive_t *, int);
/* check host's drive quirk list */ /* check host's drive quirk list */
int (*quirkproc)(ide_drive_t *); void (*quirkproc)(ide_drive_t *);
/* driver soft-power interface */ /* driver soft-power interface */
int (*busproc)(ide_drive_t *, int); int (*busproc)(ide_drive_t *, int);
#endif #endif
u8 (*mdma_filter)(ide_drive_t *); u8 (*mdma_filter)(ide_drive_t *);
u8 (*udma_filter)(ide_drive_t *); u8 (*udma_filter)(ide_drive_t *);
void (*fixup)(struct hwif_s *);
void (*ata_input_data)(ide_drive_t *, void *, u32); void (*ata_input_data)(ide_drive_t *, void *, u32);
void (*ata_output_data)(ide_drive_t *, void *, u32); void (*ata_output_data)(ide_drive_t *, void *, u32);
void (*atapi_input_bytes)(ide_drive_t *, void *, u32); void (*atapi_input_bytes)(ide_drive_t *, void *, u32);
void (*atapi_output_bytes)(ide_drive_t *, void *, u32); void (*atapi_output_bytes)(ide_drive_t *, void *, u32);
void (*dma_host_set)(ide_drive_t *, int);
int (*dma_setup)(ide_drive_t *); int (*dma_setup)(ide_drive_t *);
void (*dma_exec_cmd)(ide_drive_t *, u8); void (*dma_exec_cmd)(ide_drive_t *, u8);
void (*dma_start)(ide_drive_t *); void (*dma_start)(ide_drive_t *);
int (*ide_dma_end)(ide_drive_t *drive); int (*ide_dma_end)(ide_drive_t *drive);
int (*ide_dma_on)(ide_drive_t *drive);
void (*dma_off_quietly)(ide_drive_t *drive);
int (*ide_dma_test_irq)(ide_drive_t *drive); int (*ide_dma_test_irq)(ide_drive_t *drive);
void (*ide_dma_clear_irq)(ide_drive_t *drive); void (*ide_dma_clear_irq)(ide_drive_t *drive);
void (*dma_host_on)(ide_drive_t *drive);
void (*dma_host_off)(ide_drive_t *drive);
void (*dma_lost_irq)(ide_drive_t *drive); void (*dma_lost_irq)(ide_drive_t *drive);
void (*dma_timeout)(ide_drive_t *drive); void (*dma_timeout)(ide_drive_t *drive);
...@@ -874,14 +870,6 @@ extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t); ...@@ -874,14 +870,6 @@ extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t);
extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
/*
* Issue ATA command and wait for completion.
* Use for implementing commands in kernel
*
* (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
*/
extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *);
enum { enum {
IDE_TFLAG_LBA48 = (1 << 0), IDE_TFLAG_LBA48 = (1 << 0),
IDE_TFLAG_NO_SELECT_MASK = (1 << 1), IDE_TFLAG_NO_SELECT_MASK = (1 << 1),
...@@ -934,6 +922,14 @@ enum { ...@@ -934,6 +922,14 @@ enum {
IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT | IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT |
IDE_TFLAG_IN_LBA, IDE_TFLAG_IN_LBA,
IDE_TFLAG_IN_DEVICE = (1 << 29), IDE_TFLAG_IN_DEVICE = (1 << 29),
IDE_TFLAG_HOB = IDE_TFLAG_OUT_HOB |
IDE_TFLAG_IN_HOB,
IDE_TFLAG_TF = IDE_TFLAG_OUT_TF |
IDE_TFLAG_IN_TF,
IDE_TFLAG_DEVICE = IDE_TFLAG_OUT_DEVICE |
IDE_TFLAG_IN_DEVICE,
/* force 16-bit I/O operations */
IDE_TFLAG_IO_16BIT = (1 << 30),
}; };
struct ide_taskfile { struct ide_taskfile {
...@@ -988,6 +984,10 @@ void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); ...@@ -988,6 +984,10 @@ void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8);
ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);
void task_end_request(ide_drive_t *, struct request *, u8);
u8 wait_drive_not_busy(ide_drive_t *);
int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16); int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16);
int ide_no_data_taskfile(ide_drive_t *, ide_task_t *); int ide_no_data_taskfile(ide_drive_t *, ide_task_t *);
...@@ -1015,10 +1015,9 @@ extern void do_ide_request(struct request_queue *); ...@@ -1015,10 +1015,9 @@ extern void do_ide_request(struct request_queue *);
void ide_init_disk(struct gendisk *, ide_drive_t *); void ide_init_disk(struct gendisk *, ide_drive_t *);
extern int ideprobe_init(void);
#ifdef CONFIG_IDEPCI_PCIBUS_ORDER #ifdef CONFIG_IDEPCI_PCIBUS_ORDER
extern void ide_scan_pcibus(int scan_direction) __init; extern int ide_scan_direction;
int __init ide_scan_pcibus(void);
extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner, const char *mod_name); extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner, const char *mod_name);
#define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE, KBUILD_MODNAME) #define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE, KBUILD_MODNAME)
#else #else
...@@ -1095,6 +1094,8 @@ enum { ...@@ -1095,6 +1094,8 @@ enum {
/* unmask IRQs */ /* unmask IRQs */
IDE_HFLAG_UNMASK_IRQS = (1 << 25), IDE_HFLAG_UNMASK_IRQS = (1 << 25),
IDE_HFLAG_ABUSE_SET_DMA_MODE = (1 << 26), IDE_HFLAG_ABUSE_SET_DMA_MODE = (1 << 26),
/* host is CY82C693 */
IDE_HFLAG_CY82C693 = (1 << 27),
}; };
#ifdef CONFIG_BLK_DEV_OFFBOARD #ifdef CONFIG_BLK_DEV_OFFBOARD
...@@ -1109,7 +1110,6 @@ struct ide_port_info { ...@@ -1109,7 +1110,6 @@ struct ide_port_info {
void (*init_iops)(ide_hwif_t *); void (*init_iops)(ide_hwif_t *);
void (*init_hwif)(ide_hwif_t *); void (*init_hwif)(ide_hwif_t *);
void (*init_dma)(ide_hwif_t *, unsigned long); void (*init_dma)(ide_hwif_t *, unsigned long);
void (*fixup)(ide_hwif_t *);
ide_pci_enablebit_t enablebits[2]; ide_pci_enablebit_t enablebits[2];
hwif_chipset_t chipset; hwif_chipset_t chipset;
u8 extra; u8 extra;
...@@ -1147,7 +1147,9 @@ static inline u8 ide_max_dma_mode(ide_drive_t *drive) ...@@ -1147,7 +1147,9 @@ static inline u8 ide_max_dma_mode(ide_drive_t *drive)
return ide_find_dma_mode(drive, XFER_UDMA_6); return ide_find_dma_mode(drive, XFER_UDMA_6);
} }
void ide_dma_off_quietly(ide_drive_t *);
void ide_dma_off(ide_drive_t *); void ide_dma_off(ide_drive_t *);
void ide_dma_on(ide_drive_t *);
int ide_set_dma(ide_drive_t *); int ide_set_dma(ide_drive_t *);
ide_startstop_t ide_dma_intr(ide_drive_t *); ide_startstop_t ide_dma_intr(ide_drive_t *);
...@@ -1158,10 +1160,7 @@ extern void ide_destroy_dmatable(ide_drive_t *); ...@@ -1158,10 +1160,7 @@ extern void ide_destroy_dmatable(ide_drive_t *);
extern int ide_release_dma(ide_hwif_t *); extern int ide_release_dma(ide_hwif_t *);
extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int); extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int);
void ide_dma_host_off(ide_drive_t *); void ide_dma_host_set(ide_drive_t *, int);
void ide_dma_off_quietly(ide_drive_t *);
void ide_dma_host_on(ide_drive_t *);
extern int __ide_dma_on(ide_drive_t *);
extern int ide_dma_setup(ide_drive_t *); extern int ide_dma_setup(ide_drive_t *);
extern void ide_dma_start(ide_drive_t *); extern void ide_dma_start(ide_drive_t *);
extern int __ide_dma_end(ide_drive_t *); extern int __ide_dma_end(ide_drive_t *);
...@@ -1173,7 +1172,9 @@ extern void ide_dma_timeout(ide_drive_t *); ...@@ -1173,7 +1172,9 @@ extern void ide_dma_timeout(ide_drive_t *);
static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; } static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; }
static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; } static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; }
static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; } static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
static inline void ide_dma_off_quietly(ide_drive_t *drive) { ; }
static inline void ide_dma_off(ide_drive_t *drive) { ; } static inline void ide_dma_off(ide_drive_t *drive) { ; }
static inline void ide_dma_on(ide_drive_t *drive) { ; }
static inline void ide_dma_verbose(ide_drive_t *drive) { ; } static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
static inline int ide_set_dma(ide_drive_t *drive) { return 1; } static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif /* CONFIG_BLK_DEV_IDEDMA */
...@@ -1203,8 +1204,9 @@ extern void ide_unregister (unsigned int index); ...@@ -1203,8 +1204,9 @@ extern void ide_unregister (unsigned int index);
void ide_register_region(struct gendisk *); void ide_register_region(struct gendisk *);
void ide_unregister_region(struct gendisk *); void ide_unregister_region(struct gendisk *);
void ide_undecoded_slave(ide_hwif_t *); void ide_undecoded_slave(ide_drive_t *);
int ide_device_add_all(u8 *idx);
int ide_device_add(u8 idx[4]); int ide_device_add(u8 idx[4]);
static inline void *ide_get_hwifdata (ide_hwif_t * hwif) static inline void *ide_get_hwifdata (ide_hwif_t * hwif)
...@@ -1302,4 +1304,9 @@ static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive) ...@@ -1302,4 +1304,9 @@ static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive)
return &hwif->drives[(drive->dn ^ 1) & 1]; return &hwif->drives[(drive->dn ^ 1) & 1];
} }
static inline void ide_set_irq(ide_drive_t *drive, int on)
{
drive->hwif->OUTB(drive->ctl | (on ? 0 : 2), IDE_CONTROL_REG);
}
#endif /* _IDE_H */ #endif /* _IDE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment