提交 c09bca78 编写于 作者: L 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: (59 commits)
  ide-floppy: do not complete rq's prematurely
  ide: be able to build pmac driver without IDE built-in
  ide-pmac: IDE cable detection on Apple PowerBook
  ide: inline SELECT_DRIVE()
  ide: turn selectproc() method into dev_select() method (take 5)
  MAINTAINERS: move old ide-{floppy,tape} entries to CREDITS (take 2)
  ide: move data register access out of tf_{read|load}() methods (take 2)
  ide: call {in|out}put_data() methods from tf_{read|load}() methods (take 2)
  ide-io-std: shorten ide_{in|out}put_data()
  ide: rename IDE_TFLAG_IN_[HOB_]FEATURE
  ide: turn set_irq() method into write_devctl() method
  ide: use ATA_HOB
  ide-disk: use ATA_ERR
  ide: add support for CFA specified transfer modes (take 3)
  ide-iops: only clear DMA words on setting DMA mode
  ide: identify data word 53 bit 1 doesn't cover words 62 and 63 (take 3)
  au1xxx-ide: auide_{in|out}sw() should be static
  ide-floppy: use ide_pio_bytes()
  ide-{floppy,tape}: fix padding for PIO transfers
  ide: remove CONFIG_BLK_DEV_IDEDOUBLER config option
  ...
......@@ -495,6 +495,11 @@ S: Kopmansg 2
S: 411 13 Goteborg
S: Sweden
N: Paul Bristow
E: paul@paulbristow.net
W: http://paulbristow.net/linux/idefloppy.html
D: Maintainer of IDE/ATAPI floppy driver
N: Dominik Brodowski
E: linux@brodo.de
W: http://www.brodo.de/
......@@ -2642,6 +2647,10 @@ S: C/ Mieses 20, 9-B
S: Valladolid 47009
S: Spain
N: Gadi Oxman
E: gadio@netvision.net.il
D: Original author and maintainer of IDE/ATAPI floppy/tape drivers
N: Greg Page
E: gpage@sovereign.org
D: IPX development and support
......
......@@ -2202,25 +2202,12 @@ L: linux-ide@vger.kernel.org
T: quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/
S: Maintained
IDE/ATAPI CDROM DRIVER
IDE/ATAPI DRIVERS
P: Borislav Petkov
M: petkovbb@gmail.com
L: linux-ide@vger.kernel.org
S: Maintained
IDE/ATAPI FLOPPY DRIVERS
P: Paul Bristow
M: Paul Bristow <paul@paulbristow.net>
W: http://paulbristow.net/linux/idefloppy.html
L: linux-kernel@vger.kernel.org
S: Maintained
IDE/ATAPI TAPE DRIVERS
P: Gadi Oxman
M: Gadi Oxman <gadio@netvision.net.il>
L: linux-kernel@vger.kernel.org
S: Maintained
IDLE-I7300
P: Andy Henroid
M: andrew.d.henroid@intel.com
......
......@@ -222,7 +222,8 @@ comment "IDE chipset support/bugfixes"
config IDE_GENERIC
tristate "generic/default IDE chipset support"
depends on ALPHA || X86 || IA64 || M32R || MIPS
depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC || ARCH_SHARK
default ARM && (ARCH_RPC || ARCH_SHARK)
help
This is the generic IDE driver. This driver attaches to the
fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and
......@@ -680,7 +681,7 @@ endif
# TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF
config BLK_DEV_IDE_PMAC
tristate "PowerMac on-board IDE support"
depends on PPC_PMAC && IDE=y
depends on PPC_PMAC
select IDE_TIMINGS
select BLK_DEV_IDEDMA_PCI
help
......@@ -731,11 +732,6 @@ config BLK_DEV_IDE_AT91
depends on ARM && ARCH_AT91 && !ARCH_AT91RM9200 && !ARCH_AT91X40
select IDE_TIMINGS
config IDE_ARM
tristate "ARM IDE support"
depends on ARM && (ARCH_RPC || ARCH_SHARK)
default y
config BLK_DEV_IDE_ICSIDE
tristate "ICS IDE interface support"
depends on ARM && ARCH_ACORN
......@@ -774,27 +770,20 @@ config BLK_DEV_GAYLE
This includes on-board IDE interfaces on some Amiga models (A600,
A1200, A4000, and A4000T), and IDE interfaces on the Zorro expansion
bus (M-Tech E-Matrix 530 expansion card).
Say Y if you have an Amiga with a Gayle IDE interface and want to use
IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
it.
Note that you also have to enable Zorro bus support if you want to
use Gayle IDE interfaces on the Zorro expansion bus.
config BLK_DEV_IDEDOUBLER
bool "Amiga IDE Doubler support (EXPERIMENTAL)"
depends on BLK_DEV_GAYLE && EXPERIMENTAL
---help---
This feature provides support for the so-called `IDE doublers' (made
It also provides support for the so-called `IDE doublers' (made
by various manufacturers, e.g. Eyetech) that can be connected to
the on-board IDE interface of some Amiga models. Using such an IDE
doubler, you can connect up to four instead of two IDE devices to
the Amiga's on-board IDE interface.
the Amiga's on-board IDE interface. The feature is enabled at kernel
runtime using the "gayle.doubler" kernel boot parameter.
Note that the normal Amiga Gayle IDE driver may not work correctly
if you have an IDE doubler and don't enable this feature!
Say Y if you have an Amiga with a Gayle IDE interface and want to use
IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
it.
Say Y if you have an IDE doubler. The feature is enabled at kernel
runtime using the "gayle.doubler" kernel boot parameter.
Note that you also have to enable Zorro bus support if you want to
use Gayle IDE interfaces on the Zorro expansion bus.
config BLK_DEV_BUDDHA
tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
......
......@@ -21,8 +21,6 @@ ide-core-$(CONFIG_IDE_LEGACY) += ide-legacy.o
obj-$(CONFIG_IDE) += ide-core.o
obj-$(CONFIG_IDE_ARM) += ide_arm.o
obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o
obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o
......
......@@ -189,20 +189,20 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
/**
* ali15x3_dma_setup - begin a DMA phase
* ali_dma_check - DMA check
* @drive: target device
* @cmd: command
*
* Returns 1 if the DMA cannot be performed, zero on success.
*/
static int ali15x3_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
static int ali_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
{
if (m5229_revision < 0xC2 && drive->media != ide_disk) {
if (cmd->tf_flags & IDE_TFLAG_WRITE)
return 1; /* try PIO instead of DMA */
}
return ide_dma_setup(drive, cmd);
return 0;
}
/**
......@@ -503,13 +503,13 @@ static const struct ide_port_ops ali_port_ops = {
static const struct ide_dma_ops ali_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ali15x3_dma_setup,
.dma_setup = ide_dma_setup,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_check = ali_dma_check,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......
......@@ -192,15 +192,9 @@ static void at91_ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_taskfile *tf = &cmd->tf;
u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
if (cmd->tf_flags & IDE_FTFLAG_FLAGGED)
if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
if (cmd->tf_flags & IDE_FTFLAG_OUT_DATA) {
u16 data = (tf->hob_data << 8) | tf->data;
at91_ide_output_data(drive, NULL, &data, 2);
}
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
ide_mm_outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
......@@ -233,19 +227,11 @@ static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
if (cmd->tf_flags & IDE_FTFLAG_IN_DATA) {
u16 data;
at91_ide_input_data(drive, NULL, &data, 2);
tf->data = data & 0xff;
tf->hob_data = (data >> 8) & 0xff;
}
/* be sure we're looking at the low order bits */
ide_mm_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
ide_mm_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = ide_mm_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
tf->error = ide_mm_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = ide_mm_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
......@@ -258,18 +244,18 @@ static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = ide_mm_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
ide_mm_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
ide_mm_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = ide_mm_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
tf->hob_error = ide_mm_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr);
tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr);
tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr);
tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr);
tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr);
}
}
......@@ -295,8 +281,9 @@ static const struct ide_tp_ops at91_ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.set_irq = ide_set_irq,
.write_devctl = ide_write_devctl,
.dev_select = ide_dev_select,
.tf_load = at91_ide_tf_load,
.tf_read = at91_ide_tf_read,
......
......@@ -50,7 +50,7 @@ static _auide_hwif auide_hwif;
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
void auide_insw(unsigned long port, void *addr, u32 count)
static inline void auide_insw(unsigned long port, void *addr, u32 count)
{
_auide_hwif *ahwif = &auide_hwif;
chan_tab_t *ctp;
......@@ -68,7 +68,7 @@ void auide_insw(unsigned long port, void *addr, u32 count)
ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
void auide_outsw(unsigned long port, void *addr, u32 count)
static inline void auide_outsw(unsigned long port, void *addr, u32 count)
{
_auide_hwif *ahwif = &auide_hwif;
chan_tab_t *ctp;
......@@ -236,7 +236,7 @@ static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
if (++count >= PRD_ENTRIES) {
printk(KERN_WARNING "%s: DMA table too small\n",
drive->name);
goto use_pio_instead;
return 0;
}
/* Lets enable intr for the last descriptor only */
......@@ -272,16 +272,11 @@ static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
if (count)
return 1;
use_pio_instead:
ide_destroy_dmatable(drive);
return 0; /* revert to PIO for this request */
}
static int auide_dma_end(ide_drive_t *drive)
{
ide_destroy_dmatable(drive);
return 0;
}
......@@ -292,12 +287,9 @@ static void auide_dma_start(ide_drive_t *drive )
static int auide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
if (auide_build_dmatable(drive, cmd) == 0) {
ide_map_sg(drive, cmd);
if (auide_build_dmatable(drive, cmd) == 0)
return 1;
}
drive->waiting_for_dma = 1;
return 0;
}
......@@ -322,16 +314,11 @@ static void auide_dma_host_set(ide_drive_t *drive, int on)
static void auide_ddma_tx_callback(int irq, void *param)
{
_auide_hwif *ahwif = (_auide_hwif*)param;
ahwif->drive->waiting_for_dma = 0;
}
static void auide_ddma_rx_callback(int irq, void *param)
{
_auide_hwif *ahwif = (_auide_hwif*)param;
ahwif->drive->waiting_for_dma = 0;
}
#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
......@@ -353,7 +340,6 @@ static const struct ide_dma_ops au1xxx_dma_ops = {
.dma_end = auide_dma_end,
.dma_test_irq = auide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
};
static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
......@@ -481,9 +467,9 @@ static const struct ide_tp_ops au1xxx_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.set_irq = ide_set_irq,
.dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
......
......@@ -318,7 +318,6 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
drive->waiting_for_dma = 0;
/* get DMA status */
dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
/* read DMA command state */
......@@ -327,8 +326,6 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
/* clear the INTR & ERROR bits */
outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
/* and free any DMA resources */
ide_destroy_dmatable(drive);
/* verify good DMA status */
return (dma_stat & 7) != 4;
}
......@@ -384,7 +381,6 @@ static const struct ide_dma_ops cmd64x_dma_ops = {
.dma_test_irq = cmd64x_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......@@ -396,7 +392,6 @@ static const struct ide_dma_ops cmd646_rev1_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......@@ -408,7 +403,6 @@ static const struct ide_dma_ops cmd648_dma_ops = {
.dma_test_irq = cmd648_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......
......@@ -92,8 +92,7 @@ static u8 cs5530_udma_filter(ide_drive_t *drive)
if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
(mateid[ATA_ID_UDMA_MODES] & 7))
goto out;
if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
(mateid[ATA_ID_MWDMA_MODES] & 7))
if (mateid[ATA_ID_MWDMA_MODES] & 7)
mask = 0;
}
out:
......
......@@ -236,7 +236,6 @@ static const struct ide_dma_ops cs5536_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
};
static const struct ide_port_info cs5536_info = {
......
......@@ -89,9 +89,9 @@ static const struct ide_tp_ops falconide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.set_irq = ide_set_irq,
.dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
......
......@@ -53,11 +53,6 @@
#define GAYLE_NEXT_PORT 0x1000
#ifndef CONFIG_BLK_DEV_IDEDOUBLER
#define GAYLE_NUM_HWIFS 1
#define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS
#define GAYLE_HAS_CONTROL_REG 1
#else /* CONFIG_BLK_DEV_IDEDOUBLER */
#define GAYLE_NUM_HWIFS 2
#define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \
GAYLE_NUM_HWIFS-1)
......@@ -66,8 +61,6 @@
static int ide_doubler;
module_param_named(doubler, ide_doubler, bool, 0);
MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
/*
* Check and acknowledge the interrupt status
......@@ -151,10 +144,7 @@ static int __init gayle_init(void)
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
"");
ide_doubler ? ", IDE doubler" : "");
if (a4000) {
phys_base = GAYLE_BASE_4000;
......
......@@ -835,12 +835,6 @@ static int hpt370_dma_end(ide_drive_t *drive)
return ide_dma_end(drive);
}
static void hpt370_dma_timeout(ide_drive_t *drive)
{
hpt370_irq_timeout(drive);
ide_dma_timeout(drive);
}
/* returns 1 if DMA IRQ issued, 0 otherwise */
static int hpt374_dma_test_irq(ide_drive_t *drive)
{
......@@ -1423,7 +1417,6 @@ static const struct ide_dma_ops hpt37x_dma_ops = {
.dma_test_irq = hpt374_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......@@ -1435,7 +1428,7 @@ static const struct ide_dma_ops hpt370_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = hpt370_dma_timeout,
.dma_clear = hpt370_irq_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......@@ -1447,7 +1440,6 @@ static const struct ide_dma_ops hpt36x_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = hpt366_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......
......@@ -103,7 +103,7 @@
/*
* This routine is invoked from ide.c to prepare for access to a given drive.
*/
static void ht6560b_selectproc (ide_drive_t *drive)
static void ht6560b_dev_select(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
......@@ -143,6 +143,8 @@ static void ht6560b_selectproc (ide_drive_t *drive)
#endif
}
local_irq_restore(flags);
outb(drive->select | ATA_DEVICE_OBS, hwif->io_ports.device_addr);
}
/*
......@@ -305,15 +307,29 @@ static int probe_ht6560b;
module_param_named(probe, probe_ht6560b, bool, 0);
MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
static const struct ide_tp_ops ht6560b_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.dev_select = ht6560b_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
.input_data = ide_input_data,
.output_data = ide_output_data,
};
static const struct ide_port_ops ht6560b_port_ops = {
.init_dev = ht6560b_init_dev,
.set_pio_mode = ht6560b_set_pio_mode,
.selectproc = ht6560b_selectproc,
};
static const struct ide_port_info ht6560b_port_info __initdata = {
.name = DRV_NAME,
.chipset = ide_ht6560b,
.tp_ops = &ht6560b_tp_ops,
.port_ops = &ht6560b_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE | /* is this needed? */
IDE_HFLAG_NO_DMA |
......
......@@ -287,13 +287,8 @@ static int icside_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
drive->waiting_for_dma = 0;
disable_dma(ec->dma);
/* Teardown mappings after DMA has completed. */
ide_destroy_dmatable(drive);
return get_dma_residue(ec->dma) != 0;
}
......@@ -346,8 +341,6 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
set_dma_sg(ec->dma, hwif->sg_table, cmd->sg_nents);
set_dma_mode(ec->dma, dma_mode);
drive->waiting_for_dma = 1;
return 0;
}
......@@ -377,7 +370,6 @@ static const struct ide_dma_ops icside_v6_dma_ops = {
.dma_start = icside_dma_start,
.dma_end = icside_dma_end,
.dma_test_irq = icside_dma_test_irq,
.dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
};
#else
......
......@@ -6,6 +6,8 @@
#include <linux/cdrom.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/scatterlist.h>
#include <scsi/scsi.h>
#ifdef DEBUG
......@@ -69,56 +71,6 @@ int ide_check_atapi_device(ide_drive_t *drive, const char *s)
}
EXPORT_SYMBOL_GPL(ide_check_atapi_device);
/* PIO data transfer routine using the scatter gather table. */
int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount, int write)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data;
struct scatterlist *sg = pc->sg;
char *buf;
int count, done = 0;
while (bcount) {
count = min(sg->length - pc->b_count, bcount);
if (PageHighMem(sg_page(sg))) {
unsigned long flags;
local_irq_save(flags);
buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
xf(drive, NULL, buf + pc->b_count, count);
kunmap_atomic(buf - sg->offset, KM_IRQ0);
local_irq_restore(flags);
} else {
buf = sg_virt(sg);
xf(drive, NULL, buf + pc->b_count, count);
}
bcount -= count;
pc->b_count += count;
done += count;
if (pc->b_count == sg->length) {
if (!--pc->sg_cnt)
break;
pc->sg = sg = sg_next(sg);
pc->b_count = 0;
}
}
if (bcount) {
printk(KERN_ERR "%s: %d leftover bytes, %s\n", drive->name,
bcount, write ? "padding with zeros"
: "discarding data");
ide_pad_transfer(drive, write, bcount);
}
return done;
}
EXPORT_SYMBOL_GPL(ide_io_buffers);
void ide_init_pc(struct ide_atapi_pc *pc)
{
memset(pc, 0, sizeof(*pc));
......@@ -324,12 +276,14 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
{
struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xferfunc;
unsigned int timeout, temp;
unsigned int timeout, done;
u16 bcount;
u8 stat, ireason, dsc = 0;
u8 write = !!(pc->flags & PC_FLAG_WRITING);
debug_log("Enter %s - interrupt handler\n", __func__);
......@@ -340,8 +294,13 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
stat = tp_ops->read_status(hwif);
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
if (hwif->dma_ops->dma_end(drive) ||
(drive->media == ide_tape && (stat & ATA_ERR))) {
int rc;
drive->waiting_for_dma = 0;
rc = hwif->dma_ops->dma_end(drive);
ide_dma_unmap_sg(drive, cmd);
if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) {
if (drive->media == ide_floppy)
printk(KERN_ERR "%s: DMA %s error\n",
drive->name, rq_data_dir(pc->rq)
......@@ -357,7 +316,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
/* No more interrupts */
if ((stat & ATA_DRQ) == 0) {
int uptodate;
int uptodate, error;
unsigned int done;
debug_log("Packet command completed, %d bytes transferred\n",
pc->xferred);
......@@ -404,16 +364,24 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
if (blk_special_request(rq)) {
rq->errors = 0;
ide_complete_rq(drive, 0, blk_rq_bytes(rq));
done = blk_rq_bytes(rq);
error = 0;
} else {
if (blk_fs_request(rq) == 0 && uptodate <= 0) {
if (rq->errors == 0)
rq->errors = -EIO;
}
ide_complete_rq(drive, uptodate ? 0 : -EIO,
ide_rq_bytes(rq));
if (drive->media == ide_tape)
done = ide_rq_bytes(rq); /* FIXME */
else
done = blk_rq_bytes(rq);
error = uptodate ? 0 : -EIO;
}
ide_complete_rq(drive, error, done);
return ide_stopped;
}
......@@ -433,8 +401,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive);
}
if (((ireason & ATAPI_IO) == ATAPI_IO) ==
!!(pc->flags & PC_FLAG_WRITING)) {
if (((ireason & ATAPI_IO) == ATAPI_IO) == write) {
/* Hopefully, we will never get here */
printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
"to %s!\n", drive->name,
......@@ -443,45 +410,30 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive);
}
if (!(pc->flags & PC_FLAG_WRITING)) {
/* Reading - Check that we have enough space */
temp = pc->xferred + bcount;
if (temp > pc->req_xfer) {
if (temp > pc->buf_size) {
printk(KERN_ERR "%s: The device wants to send "
"us more data than expected - "
"discarding data\n",
drive->name);
ide_pad_transfer(drive, 0, bcount);
goto next_irq;
}
debug_log("The device wants to send us more data than "
"expected - allowing transfer\n");
}
xferfunc = tp_ops->input_data;
} else
xferfunc = tp_ops->output_data;
if ((drive->media == ide_floppy && !pc->buf) ||
(drive->media == ide_tape && pc->bh)) {
int done = drive->pc_io_buffers(drive, pc, bcount,
!!(pc->flags & PC_FLAG_WRITING));
/* FIXME: don't do partial completions */
if (drive->media == ide_floppy)
ide_complete_rq(drive, 0,
done ? done : ide_rq_bytes(rq));
} else
xferfunc(drive, NULL, pc->cur_pos, bcount);
xferfunc = write ? tp_ops->output_data : tp_ops->input_data;
if (drive->media == ide_floppy && pc->buf == NULL) {
done = min_t(unsigned int, bcount, cmd->nleft);
ide_pio_bytes(drive, cmd, write, done);
} else if (drive->media == ide_tape && pc->bh) {
done = drive->pc_io_buffers(drive, pc, bcount, write);
} else {
done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred);
xferfunc(drive, NULL, pc->cur_pos, done);
}
/* Update the current position */
pc->xferred += bcount;
pc->cur_pos += bcount;
pc->xferred += done;
pc->cur_pos += done;
bcount -= done;
if (bcount)
ide_pad_transfer(drive, write, bcount);
debug_log("[cmd %x] transferred %d bytes, padded %d bytes\n",
rq->cmd[0], done, bcount);
debug_log("[cmd %x] transferred %d bytes on that intr.\n",
rq->cmd[0], bcount);
next_irq:
/* And set the interrupt handler again */
ide_set_handler(drive, ide_pc_intr, timeout);
return ide_started;
......@@ -611,6 +563,10 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
: ide_pc_intr),
timeout);
/* Send the actual packet */
if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
/* Begin DMA, if necessary */
if (dev_is_idecd(drive)) {
if (drive->dma)
......@@ -622,10 +578,6 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
}
}
/* Send the actual packet */
if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
return ide_started;
}
......@@ -633,7 +585,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_atapi_pc *pc;
ide_hwif_t *hwif = drive->hwif;
const struct ide_dma_ops *dma_ops = hwif->dma_ops;
ide_expiry_t *expiry = NULL;
struct request *rq = hwif->rq;
unsigned int timeout;
......@@ -647,12 +598,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
expiry = ide_cd_expiry;
timeout = ATAPI_WAIT_PC;
if (drive->dma) {
if (ide_build_sglist(drive, cmd))
drive->dma = !dma_ops->dma_setup(drive, cmd);
else
drive->dma = 0;
}
if (drive->dma)
drive->dma = !ide_dma_prepare(drive, cmd);
} else {
pc = drive->pc;
......@@ -670,13 +617,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
ide_dma_off(drive);
}
if ((pc->flags & PC_FLAG_DMA_OK) &&
(drive->dev_flags & IDE_DFLAG_USING_DMA)) {
if (ide_build_sglist(drive, cmd))
drive->dma = !dma_ops->dma_setup(drive, cmd);
else
drive->dma = 0;
}
if (pc->flags & PC_FLAG_DMA_OK)
drive->dma = !ide_dma_prepare(drive, cmd);
if (!drive->dma)
pc->flags &= ~PC_FLAG_DMA_OK;
......
此差异已折叠。
......@@ -227,7 +227,7 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
ide_no_data_taskfile(drive, &cmd);
/* if OK, compute maximum address value */
if ((tf->status & 0x01) == 0)
if (!(tf->status & ATA_ERR))
addr = ide_get_lba_addr(tf, lba48) + 1;
return addr;
......@@ -267,7 +267,7 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
ide_no_data_taskfile(drive, &cmd);
/* if OK, compute maximum address value */
if ((tf->status & 0x01) == 0)
if (!(tf->status & ATA_ERR))
addr_set = ide_get_lba_addr(tf, lba48) + 1;
return addr_set;
......
......@@ -38,10 +38,9 @@ int config_drive_for_dma(ide_drive_t *drive)
* Enable DMA on any drive that has mode2 DMA
* (multi or single) enabled
*/
if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */
if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
(id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
return 1;
if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
(id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
return 1;
/* Consult the list of known "good" drives */
if (ide_dma_good_drive(drive))
......@@ -166,8 +165,6 @@ int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");
ide_destroy_dmatable(drive);
return 0; /* revert to PIO for this request */
}
EXPORT_SYMBOL_GPL(ide_build_dmatable);
......@@ -218,7 +215,6 @@ int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
/* clear INTR & ERROR flags */
ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
drive->waiting_for_dma = 1;
return 0;
}
EXPORT_SYMBOL_GPL(ide_dma_setup);
......@@ -292,8 +288,6 @@ int ide_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0, mask;
drive->waiting_for_dma = 0;
/* stop DMA */
if (hwif->host_flags & IDE_HFLAG_MMIO) {
dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
......@@ -310,8 +304,6 @@ int ide_dma_end(ide_drive_t *drive)
/* clear INTR & ERROR bits */
ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
/* purge DMA mappings */
ide_destroy_dmatable(drive);
wmb();
/* verify good DMA status */
......@@ -338,9 +330,8 @@ const struct ide_dma_ops sff_dma_ops = {
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
EXPORT_SYMBOL_GPL(sff_dma_ops);
......@@ -89,15 +89,16 @@ static const struct drive_list_entry drive_blacklist[] = {
ide_startstop_t ide_dma_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_cmd *cmd = &hwif->cmd;
u8 stat = 0, dma_stat = 0;
drive->waiting_for_dma = 0;
dma_stat = hwif->dma_ops->dma_end(drive);
ide_dma_unmap_sg(drive, cmd);
stat = hwif->tp_ops->read_status(hwif);
if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) {
if (!dma_stat) {
struct ide_cmd *cmd = &hwif->cmd;
if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
ide_finish_cmd(drive, cmd, stat);
else
......@@ -117,8 +118,8 @@ int ide_dma_good_drive(ide_drive_t *drive)
}
/**
* ide_build_sglist - map IDE scatter gather for DMA I/O
* @drive: the drive to build the DMA table for
* ide_dma_map_sg - map IDE scatter gather for DMA I/O
* @drive: the drive to map the DMA table for
* @cmd: command
*
* Perform the DMA mapping magic necessary to access the source or
......@@ -127,23 +128,19 @@ int ide_dma_good_drive(ide_drive_t *drive)
* operate in a portable fashion.
*/
int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd)
static int ide_dma_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
int i;
ide_map_sg(drive, cmd);
if (cmd->tf_flags & IDE_TFLAG_WRITE)
cmd->sg_dma_direction = DMA_TO_DEVICE;
else
cmd->sg_dma_direction = DMA_FROM_DEVICE;
i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction);
if (i == 0)
ide_map_sg(drive, cmd);
else {
if (i) {
cmd->orig_sg_nents = cmd->sg_nents;
cmd->sg_nents = i;
}
......@@ -152,7 +149,7 @@ int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd)
}
/**
* ide_destroy_dmatable - clean up DMA mapping
* ide_dma_unmap_sg - clean up DMA mapping
* @drive: The drive to unmap
*
* Teardown mappings after DMA has completed. This must be called
......@@ -162,15 +159,14 @@ int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd)
* time.
*/
void ide_destroy_dmatable(ide_drive_t *drive)
void ide_dma_unmap_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_cmd *cmd = &hwif->cmd;
dma_unmap_sg(hwif->dev, hwif->sg_table, cmd->orig_sg_nents,
cmd->sg_dma_direction);
}
EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
EXPORT_SYMBOL_GPL(ide_dma_unmap_sg);
/**
* ide_dma_off_quietly - Generic DMA kill
......@@ -249,12 +245,11 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
case XFER_UDMA_0:
if ((id[ATA_ID_FIELD_VALID] & 4) == 0)
break;
mask = id[ATA_ID_UDMA_MODES];
if (port_ops && port_ops->udma_filter)
mask = port_ops->udma_filter(drive);
mask &= port_ops->udma_filter(drive);
else
mask = hwif->ultra_mask;
mask &= id[ATA_ID_UDMA_MODES];
mask &= hwif->ultra_mask;
/*
* avoid false cable warning from eighty_ninty_three()
......@@ -265,18 +260,23 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
}
break;
case XFER_MW_DMA_0:
if ((id[ATA_ID_FIELD_VALID] & 2) == 0)
break;
mask = id[ATA_ID_MWDMA_MODES];
/* Also look for the CF specific MWDMA modes... */
if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 0x38)) {
u8 mode = ((id[ATA_ID_CFA_MODES] & 0x38) >> 3) - 1;
mask |= ((2 << mode) - 1) << 3;
}
if (port_ops && port_ops->mdma_filter)
mask = port_ops->mdma_filter(drive);
mask &= port_ops->mdma_filter(drive);
else
mask = hwif->mwdma_mask;
mask &= id[ATA_ID_MWDMA_MODES];
mask &= hwif->mwdma_mask;
break;
case XFER_SW_DMA_0:
if (id[ATA_ID_FIELD_VALID] & 2) {
mask = id[ATA_ID_SWDMA_MODES] & hwif->swdma_mask;
} else if (id[ATA_ID_OLD_DMA_MODES] >> 8) {
mask = id[ATA_ID_SWDMA_MODES];
if (!(mask & ATA_SWDMA2) && (id[ATA_ID_OLD_DMA_MODES] >> 8)) {
u8 mode = id[ATA_ID_OLD_DMA_MODES] >> 8;
/*
......@@ -284,8 +284,9 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
* (the maximum allowed mode is XFER_SW_DMA_2)
*/
if (mode <= 2)
mask = ((2 << mode) - 1) & hwif->swdma_mask;
mask = (2 << mode) - 1;
}
mask &= hwif->swdma_mask;
break;
default:
BUG();
......@@ -402,11 +403,10 @@ int ide_id_dma_bug(ide_drive_t *drive)
if ((id[ATA_ID_UDMA_MODES] >> 8) &&
(id[ATA_ID_MWDMA_MODES] >> 8))
goto err_out;
} else if (id[ATA_ID_FIELD_VALID] & 2) {
if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
(id[ATA_ID_SWDMA_MODES] >> 8))
goto err_out;
}
} else if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
(id[ATA_ID_SWDMA_MODES] >> 8))
goto err_out;
return 0;
err_out:
printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name);
......@@ -460,21 +460,6 @@ void ide_dma_lost_irq(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_dma_lost_irq);
void ide_dma_timeout(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
if (hwif->dma_ops->dma_test_irq(drive))
return;
ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));
hwif->dma_ops->dma_end(drive);
}
EXPORT_SYMBOL_GPL(ide_dma_timeout);
/*
* un-busy the port etc, and clear any pending DMA status. we want to
* retry the current request in pio mode instead of risking tossing it
......@@ -483,6 +468,8 @@ EXPORT_SYMBOL_GPL(ide_dma_timeout);
ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_dma_ops *dma_ops = hwif->dma_ops;
struct ide_cmd *cmd = &hwif->cmd;
struct request *rq;
ide_startstop_t ret = ide_stopped;
......@@ -492,12 +479,23 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
if (error < 0) {
printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
(void)hwif->dma_ops->dma_end(drive);
drive->waiting_for_dma = 0;
(void)dma_ops->dma_end(drive);
ide_dma_unmap_sg(drive, cmd);
ret = ide_error(drive, "dma timeout error",
hwif->tp_ops->read_status(hwif));
} else {
printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
hwif->dma_ops->dma_timeout(drive);
if (dma_ops->dma_clear)
dma_ops->dma_clear(drive);
printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
if (dma_ops->dma_test_irq(drive) == 0) {
ide_dump_status(drive, "DMA timeout",
hwif->tp_ops->read_status(hwif));
drive->waiting_for_dma = 0;
(void)dma_ops->dma_end(drive);
ide_dma_unmap_sg(drive, cmd);
}
}
/*
......@@ -567,3 +565,25 @@ int ide_allocate_dma_engine(ide_hwif_t *hwif)
return 0;
}
EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
int ide_dma_prepare(ide_drive_t *drive, struct ide_cmd *cmd)
{
const struct ide_dma_ops *dma_ops = drive->hwif->dma_ops;
if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
(dma_ops->dma_check && dma_ops->dma_check(drive, cmd)))
goto out;
ide_map_sg(drive, cmd);
if (ide_dma_map_sg(drive, cmd) == 0)
goto out_map;
if (dma_ops->dma_setup(drive, cmd))
goto out_dma_unmap;
drive->waiting_for_dma = 1;
return 0;
out_dma_unmap:
ide_dma_unmap_sg(drive, cmd);
out_map:
ide_map_sg(drive, cmd);
out:
return 1;
}
......@@ -165,11 +165,12 @@ static ide_startstop_t do_reset1(ide_drive_t *, int);
static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
u8 stat;
SELECT_DRIVE(drive);
tp_ops->dev_select(drive);
udelay(10);
stat = hwif->tp_ops->read_status(hwif);
stat = tp_ops->read_status(hwif);
if (OK_STAT(stat, 0, ATA_BUSY))
printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
......@@ -348,7 +349,7 @@ static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
/* For an ATAPI device, first try an ATAPI SRST. */
if (drive->media != ide_disk && !do_not_try_atapi) {
pre_reset(drive);
SELECT_DRIVE(drive);
tp_ops->dev_select(drive);
udelay(20);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
ndelay(400);
......@@ -401,15 +402,14 @@ static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
* immediate interrupt due to the edge transition it produces.
* This single interrupt gives us a "fast poll" for drives that
* recover from reset very quickly, saving us the first 50ms wait time.
*
* TODO: add ->softreset method and stop abusing ->set_irq
*/
/* set SRST and nIEN */
tp_ops->set_irq(hwif, 4);
tp_ops->write_devctl(hwif, ATA_SRST | ATA_NIEN | ATA_DEVCTL_OBS);
/* more than enough time */
udelay(10);
/* clear SRST, leave nIEN (unless device is on the quirk list) */
tp_ops->set_irq(hwif, drive->quirk_list == 2);
tp_ops->write_devctl(hwif, (drive->quirk_list == 2 ? 0 : ATA_NIEN) |
ATA_DEVCTL_OBS);
/* more than enough time */
udelay(10);
hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
......
......@@ -61,16 +61,6 @@
*/
#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */
static void idefloppy_update_buffers(ide_drive_t *drive,
struct ide_atapi_pc *pc)
{
struct request *rq = pc->rq;
struct bio *bio = rq->bio;
while ((bio = rq->bio) != NULL)
ide_complete_rq(drive, 0, ide_rq_bytes(rq));
}
static int ide_floppy_callback(ide_drive_t *drive, int dsc)
{
struct ide_disk_obj *floppy = drive->driver_data;
......@@ -213,7 +203,6 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
memcpy(rq->cmd, pc->c, 12);
pc->rq = rq;
pc->b_count = 0;
if (rq->cmd_flags & REQ_RW)
pc->flags |= PC_FLAG_WRITING;
pc->buf = NULL;
......@@ -227,7 +216,6 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
ide_init_pc(pc);
memcpy(pc->c, rq->cmd, sizeof(pc->c));
pc->rq = rq;
pc->b_count = 0;
if (rq->data_len && rq_data_dir(rq) == WRITE)
pc->flags |= PC_FLAG_WRITING;
pc->buf = rq->data;
......@@ -244,10 +232,11 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
struct request *rq, sector_t block)
{
struct ide_disk_obj *floppy = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
struct ide_cmd cmd;
struct ide_atapi_pc *pc;
ide_debug_log(IDE_DBG_FUNC, "enter, cmd: 0x%x\n", rq->cmd[0]);
if (drive->debug_mask & IDE_DBG_RQ)
blk_dump_rq_flags(rq, (rq->rq_disk
? rq->rq_disk->disk_name
......@@ -294,13 +283,10 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
cmd.rq = rq;
if (blk_fs_request(rq) || pc->req_xfer) {
ide_init_sg_cmd(&cmd, rq->nr_sectors << 9);
ide_init_sg_cmd(&cmd, pc->req_xfer);
ide_map_sg(drive, &cmd);
}
pc->sg = hwif->sg_table;
pc->sg_cnt = cmd.sg_nents;
pc->rq = rq;
return ide_floppy_issue_pc(drive, &cmd, pc);
......@@ -385,9 +371,11 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
struct gendisk *disk = floppy->disk;
struct ide_atapi_pc pc;
u8 *cap_desc;
u8 header_len, desc_cnt;
u8 pc_buf[256], header_len, desc_cnt;
int i, rc = 1, blocks, length;
ide_debug_log(IDE_DBG_FUNC, "enter");
drive->bios_cyl = 0;
drive->bios_head = drive->bios_sect = 0;
floppy->blocks = 0;
......@@ -395,6 +383,9 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
drive->capacity64 = 0;
ide_floppy_create_read_capacity_cmd(&pc);
pc.buf = &pc_buf[0];
pc.buf_size = sizeof(pc_buf);
if (ide_queue_pc_tail(drive, disk, &pc)) {
printk(KERN_ERR PFX "Can't get floppy parameters\n");
return 1;
......@@ -485,8 +476,6 @@ static void ide_floppy_setup(ide_drive_t *drive)
u16 *id = drive->id;
drive->pc_callback = ide_floppy_callback;
drive->pc_update_buffers = idefloppy_update_buffers;
drive->pc_io_buffers = ide_io_buffers;
/*
* We used to check revisions here. At this point however I'm giving up.
......
......@@ -36,9 +36,9 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
int __user *arg)
{
struct ide_disk_obj *floppy = drive->driver_data;
u8 header_len, desc_cnt;
int i, blocks, length, u_array_size, u_index;
int __user *argp;
u8 pc_buf[256], header_len, desc_cnt;
if (get_user(u_array_size, arg))
return -EFAULT;
......@@ -47,6 +47,9 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
return -EINVAL;
ide_floppy_create_read_capacity_cmd(pc);
pc->buf = &pc_buf[0];
pc->buf_size = sizeof(pc_buf);
if (ide_queue_pc_tail(drive, floppy->disk, pc)) {
printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return -EIO;
......
/*
* generic/default IDE host driver
*
* Copyright (C) 2004, 2008 Bartlomiej Zolnierkiewicz
* Copyright (C) 2004, 2008-2009 Bartlomiej Zolnierkiewicz
* This code was split off from ide.c. See it for original copyrights.
*
* May be copied or modified under the terms of the GNU General Public License.
*/
/*
* For special cases new interfaces may be added using sysfs, i.e.
*
* echo -n "0x168:0x36e:10" > /sys/class/ide_generic/add
*
* will add an interface using I/O ports 0x168-0x16f/0x36e and IRQ 10.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>
#include <linux/pci_ids.h>
/* FIXME: convert m32r to use ide_platform host driver */
/* FIXME: convert arm and m32r to use ide_platform host driver */
#ifdef CONFIG_ARM
#include <asm/irq.h>
#endif
#ifdef CONFIG_M32R
#include <asm/m32r.h>
#endif
......@@ -36,62 +31,11 @@ static const struct ide_port_info ide_generic_port_info = {
.host_flags = IDE_HFLAG_NO_DMA,
};
static ssize_t store_add(struct class *cls, const char *buf, size_t n)
{
unsigned int base, ctl;
int irq, rc;
hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3)
return -EINVAL;
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, base, ctl);
hw.irq = irq;
hw.chipset = ide_generic;
rc = ide_host_add(&ide_generic_port_info, hws, NULL);
if (rc)
return rc;
return n;
};
static struct class_attribute ide_generic_class_attrs[] = {
__ATTR(add, S_IWUSR, NULL, store_add),
__ATTR_NULL
};
static void ide_generic_class_release(struct class *cls)
{
kfree(cls);
}
static int __init ide_generic_sysfs_init(void)
{
struct class *cls;
int rc;
cls = kzalloc(sizeof(*cls), GFP_KERNEL);
if (!cls)
return -ENOMEM;
cls->name = DRV_NAME;
cls->owner = THIS_MODULE;
cls->class_release = ide_generic_class_release;
cls->class_attrs = ide_generic_class_attrs;
rc = class_register(cls);
if (rc) {
kfree(cls);
return rc;
}
return 0;
}
#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) \
|| defined(CONFIG_PLAT_OPSPUT)
#ifdef CONFIG_ARM
static const u16 legacy_bases[] = { 0x1f0 };
static const int legacy_irqs[] = { IRQ_HARDDISK };
#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || \
defined(CONFIG_PLAT_OPSPUT)
static const u16 legacy_bases[] = { 0x1f0 };
static const int legacy_irqs[] = { PLD_IRQ_CFIREQ };
#elif defined(CONFIG_PLAT_MAPPI3)
......@@ -107,11 +51,11 @@ static const int legacy_irqs[] = { 14, 15, 11, 10, 8, 12 };
static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
{
#ifdef CONFIG_PCI
struct pci_dev *p = NULL;
u16 val;
for_each_pci_dev(p) {
if (pci_resource_start(p, 0) == 0x1f0)
*primary = 1;
if (pci_resource_start(p, 2) == 0x170)
......@@ -126,7 +70,6 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
/* Intel MPIIX - PIO ATA on non PCI side of bridge */
if (p->vendor == PCI_VENDOR_ID_INTEL &&
p->device == PCI_DEVICE_ID_INTEL_82371MX) {
pci_read_config_word(p, 0x6C, &val);
if (val & 0x8000) {
/* ATA port enabled */
......@@ -137,6 +80,7 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
}
}
}
#endif
}
static int __init ide_generic_init(void)
......@@ -168,6 +112,7 @@ static int __init ide_generic_init(void)
printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX "
"not free.\n",
DRV_NAME, io_addr, io_addr + 7);
rc = -EBUSY;
continue;
}
......@@ -176,6 +121,7 @@ static int __init ide_generic_init(void)
"not free.\n",
DRV_NAME, io_addr + 0x206);
release_region(io_addr, 8);
rc = -EBUSY;
continue;
}
......@@ -196,10 +142,6 @@ static int __init ide_generic_init(void)
}
}
if (ide_generic_sysfs_init())
printk(KERN_ERR DRV_NAME ": failed to create ide_generic "
"class\n");
return rc;
}
......
......@@ -54,9 +54,6 @@ static void h8300_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA)
mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
......@@ -90,18 +87,11 @@ static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u16 data = mm_inw(io_ports->data_addr);
tf->data = data & 0xff;
tf->hob_data = (data >> 8) & 0xff;
}
/* be sure we're looking at the low order bits */
outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
tf->error = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
......@@ -114,18 +104,18 @@ static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
tf->hob_error = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = inb(io_ports->nsect_addr);
tf->hob_nsect = inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = inb(io_ports->lbal_addr);
tf->hob_lbal = inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = inb(io_ports->lbam_addr);
tf->hob_lbam = inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = inb(io_ports->lbah_addr);
tf->hob_lbah = inb(io_ports->lbah_addr);
}
}
......@@ -159,9 +149,9 @@ static const struct ide_tp_ops h8300_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.set_irq = ide_set_irq,
.dev_select = ide_dev_select,
.tf_load = h8300_tf_load,
.tf_read = h8300_tf_read,
......
......@@ -64,23 +64,26 @@ u8 ide_read_altstatus(ide_hwif_t *hwif)
}
EXPORT_SYMBOL_GPL(ide_read_altstatus);
void ide_set_irq(ide_hwif_t *hwif, int on)
void ide_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
u8 ctl = ATA_DEVCTL_OBS;
if (on == 4) { /* hack for SRST */
ctl |= 4;
on &= ~4;
}
ctl |= on ? 0 : 2;
if (hwif->host_flags & IDE_HFLAG_MMIO)
writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
else
outb(ctl, hwif->io_ports.ctl_addr);
}
EXPORT_SYMBOL_GPL(ide_set_irq);
EXPORT_SYMBOL_GPL(ide_write_devctl);
void ide_dev_select(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
u8 select = drive->select | ATA_DEVICE_OBS;
if (hwif->host_flags & IDE_HFLAG_MMIO)
writeb(select, (void __iomem *)hwif->io_ports.device_addr);
else
outb(select, hwif->io_ports.device_addr);
}
EXPORT_SYMBOL_GPL(ide_dev_select);
void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
......@@ -99,15 +102,6 @@ void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
u16 data = (tf->hob_data << 8) | tf->data;
if (mmio)
writew(data, (void __iomem *)io_ports->data_addr);
else
outw(data, io_ports->data_addr);
}
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tf_outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
......@@ -153,23 +147,11 @@ void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf_inb = ide_inb;
}
if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u16 data;
if (mmio)
data = readw((void __iomem *)io_ports->data_addr);
else
data = inw(io_ports->data_addr);
tf->data = data & 0xff;
tf->hob_data = (data >> 8) & 0xff;
}
/* be sure we're looking at the low order bits */
tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
tf_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = tf_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
tf->error = tf_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tf_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
......@@ -182,18 +164,18 @@ void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = tf_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
tf_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = tf_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
tf->hob_error = tf_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = tf_inb(io_ports->nsect_addr);
tf->hob_nsect = tf_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = tf_inb(io_ports->lbal_addr);
tf->hob_lbal = tf_inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = tf_inb(io_ports->lbam_addr);
tf->hob_lbam = tf_inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = tf_inb(io_ports->lbah_addr);
tf->hob_lbah = tf_inb(io_ports->lbah_addr);
}
}
EXPORT_SYMBOL_GPL(ide_tf_read);
......@@ -225,11 +207,10 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
unsigned long data_addr = io_ports->data_addr;
unsigned int words = (len + 1) >> 1;
u8 io_32bit = drive->io_32bit;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
len++;
if (io_32bit) {
unsigned long uninitialized_var(flags);
......@@ -238,27 +219,26 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
ata_vlb_sync(io_ports->nsect_addr);
}
words >>= 1;
if (mmio)
__ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
__ide_mm_insl((void __iomem *)data_addr, buf, words);
else
insl(data_addr, buf, len / 4);
insl(data_addr, buf, words);
if ((io_32bit & 2) && !mmio)
local_irq_restore(flags);
if ((len & 3) >= 2) {
if (mmio)
__ide_mm_insw((void __iomem *)data_addr,
(u8 *)buf + (len & ~3), 1);
else
insw(data_addr, (u8 *)buf + (len & ~3), 1);
}
} else {
if (mmio)
__ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
else
insw(data_addr, buf, len / 2);
if (((len + 1) & 3) < 2)
return;
buf += len & ~3;
words = 1;
}
if (mmio)
__ide_mm_insw((void __iomem *)data_addr, buf, words);
else
insw(data_addr, buf, words);
}
EXPORT_SYMBOL_GPL(ide_input_data);
......@@ -271,11 +251,10 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
unsigned long data_addr = io_ports->data_addr;
unsigned int words = (len + 1) >> 1;
u8 io_32bit = drive->io_32bit;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
len++;
if (io_32bit) {
unsigned long uninitialized_var(flags);
......@@ -284,27 +263,26 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
ata_vlb_sync(io_ports->nsect_addr);
}
words >>= 1;
if (mmio)
__ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
__ide_mm_outsl((void __iomem *)data_addr, buf, words);
else
outsl(data_addr, buf, len / 4);
outsl(data_addr, buf, words);
if ((io_32bit & 2) && !mmio)
local_irq_restore(flags);
if ((len & 3) >= 2) {
if (mmio)
__ide_mm_outsw((void __iomem *)data_addr,
(u8 *)buf + (len & ~3), 1);
else
outsw(data_addr, (u8 *)buf + (len & ~3), 1);
}
} else {
if (mmio)
__ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
else
outsw(data_addr, buf, len / 2);
if (((len + 1) & 3) < 2)
return;
buf += len & ~3;
words = 1;
}
if (mmio)
__ide_mm_outsw((void __iomem *)data_addr, buf, words);
else
outsw(data_addr, buf, words);
}
EXPORT_SYMBOL_GPL(ide_output_data);
......@@ -312,9 +290,9 @@ const struct ide_tp_ops default_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.set_irq = ide_set_irq,
.dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
......
......@@ -73,6 +73,7 @@ EXPORT_SYMBOL_GPL(ide_end_rq);
void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
{
const struct ide_tp_ops *tp_ops = drive->hwif->tp_ops;
struct ide_taskfile *tf = &cmd->tf;
struct request *rq = cmd->rq;
u8 tf_cmd = tf->command;
......@@ -80,7 +81,16 @@ void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
tf->error = err;
tf->status = stat;
drive->hwif->tp_ops->tf_read(drive, cmd);
if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u8 data[2];
tp_ops->input_data(drive, cmd, data, 2);
tf->data = data[0];
tf->hob_data = data[1];
}
tp_ops->tf_read(drive, cmd);
if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) &&
tf_cmd == ATA_CMD_IDLEIMMEDIATE) {
......@@ -338,7 +348,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
if (blk_pm_request(rq))
ide_check_pm_state(drive, rq);
SELECT_DRIVE(drive);
drive->hwif->tp_ops->dev_select(drive);
if (ide_wait_stat(&startstop, drive, drive->ready_stat,
ATA_BUSY | ATA_DRQ, WAIT_READY)) {
printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
......@@ -481,11 +491,10 @@ void do_ide_request(struct request_queue *q)
prev_port = hwif->host->cur_port;
hwif->rq = NULL;
if (drive->dev_flags & IDE_DFLAG_SLEEPING) {
if (time_before(drive->sleep, jiffies)) {
ide_unlock_port(hwif);
goto plug_device;
}
if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
time_after(drive->sleep, jiffies)) {
ide_unlock_port(hwif);
goto plug_device;
}
if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) &&
......@@ -495,7 +504,9 @@ void do_ide_request(struct request_queue *q)
* quirk_list may not like intr setups/cleanups
*/
if (prev_port && prev_port->cur_dev->quirk_list == 0)
prev_port->tp_ops->set_irq(prev_port, 0);
prev_port->tp_ops->write_devctl(prev_port,
ATA_NIEN |
ATA_DEVCTL_OBS);
hwif->host->cur_port = hwif;
}
......
......@@ -27,21 +27,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
void SELECT_DRIVE(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;
struct ide_cmd cmd;
if (port_ops && port_ops->selectproc)
port_ops->selectproc(drive);
memset(&cmd, 0, sizeof(cmd));
cmd.tf_flags = IDE_TFLAG_OUT_DEVICE;
drive->hwif->tp_ops->tf_load(drive, &cmd);
}
void SELECT_MASK(ide_drive_t *drive, int mask)
{
const struct ide_port_ops *port_ops = drive->hwif->port_ops;
......@@ -55,7 +40,7 @@ u8 ide_read_error(ide_drive_t *drive)
struct ide_cmd cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.tf_flags = IDE_TFLAG_IN_FEATURE;
cmd.tf_flags = IDE_TFLAG_IN_ERROR;
drive->hwif->tp_ops->tf_read(drive, &cmd);
......@@ -306,6 +291,7 @@ int ide_driveid_update(ide_drive_t *drive)
drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES];
drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES];
drive->id[ATA_ID_SWDMA_MODES] = id[ATA_ID_SWDMA_MODES];
drive->id[ATA_ID_CFA_MODES] = id[ATA_ID_CFA_MODES];
/* anything more ? */
kfree(id);
......@@ -356,10 +342,10 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
disable_irq_nosync(hwif->irq);
udelay(1);
SELECT_DRIVE(drive);
tp_ops->dev_select(drive);
SELECT_MASK(drive, 1);
udelay(1);
tp_ops->set_irq(hwif, 0);
tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
memset(&cmd, 0, sizeof(cmd));
cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
......@@ -371,7 +357,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES);
if (drive->quirk_list == 2)
tp_ops->set_irq(hwif, 1);
tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
error = __ide_wait_stat(drive, drive->ready_stat,
ATA_BUSY | ATA_DRQ | ATA_ERR,
......@@ -386,9 +372,14 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
return error;
}
id[ATA_ID_UDMA_MODES] &= ~0xFF00;
id[ATA_ID_MWDMA_MODES] &= ~0x0F00;
id[ATA_ID_SWDMA_MODES] &= ~0x0F00;
if (speed >= XFER_SW_DMA_0) {
id[ATA_ID_UDMA_MODES] &= ~0xFF00;
id[ATA_ID_MWDMA_MODES] &= ~0x0700;
id[ATA_ID_SWDMA_MODES] &= ~0x0700;
if (ata_id_is_cfa(id))
id[ATA_ID_CFA_MODES] &= ~0x0E00;
} else if (ata_id_is_cfa(id))
id[ATA_ID_CFA_MODES] &= ~0x01C0;
skip:
#ifdef CONFIG_BLK_DEV_IDEDMA
......@@ -401,12 +392,18 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
if (speed >= XFER_UDMA_0) {
i = 1 << (speed - XFER_UDMA_0);
id[ATA_ID_UDMA_MODES] |= (i << 8 | i);
} else if (ata_id_is_cfa(id) && speed >= XFER_MW_DMA_3) {
i = speed - XFER_MW_DMA_2;
id[ATA_ID_CFA_MODES] |= i << 9;
} else if (speed >= XFER_MW_DMA_0) {
i = 1 << (speed - XFER_MW_DMA_0);
id[ATA_ID_MWDMA_MODES] |= (i << 8 | i);
} else if (speed >= XFER_SW_DMA_0) {
i = 1 << (speed - XFER_SW_DMA_0);
id[ATA_ID_SWDMA_MODES] |= (i << 8 | i);
} else if (ata_id_is_cfa(id) && speed >= XFER_PIO_5) {
i = speed - XFER_PIO_4;
id[ATA_ID_CFA_MODES] |= i << 6;
}
if (!drive->init_speed)
......
......@@ -223,6 +223,7 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
* point.
*/
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
struct request_queue *q = drive->queue;
unsigned long flags;
int rc;
......@@ -232,8 +233,8 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
rc = ide_wait_not_busy(hwif, 35000);
if (rc)
printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
SELECT_DRIVE(drive);
hwif->tp_ops->set_irq(hwif, 1);
tp_ops->dev_select(drive);
tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
rc = ide_wait_not_busy(hwif, 100000);
if (rc)
printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
......
......@@ -260,7 +260,7 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
* during the identify phase that the IRQ handler isn't expecting.
*/
if (io_ports->ctl_addr)
tp_ops->set_irq(hwif, 0);
tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
/* take a deep breath */
msleep(50);
......@@ -390,13 +390,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
* (e.g. crw9624 as drive0 with disk as slave)
*/
msleep(50);
SELECT_DRIVE(drive);
tp_ops->dev_select(drive);
msleep(50);
if (ide_read_device(drive) != drive->select && present == 0) {
if (drive->dn & 1) {
/* exit with drive0 selected */
SELECT_DRIVE(hwif->devices[0]);
tp_ops->dev_select(hwif->devices[0]);
/* allow ATA_BUSY to assert & clear */
msleep(50);
}
......@@ -422,7 +422,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
printk(KERN_ERR "%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, stat);
msleep(50);
SELECT_DRIVE(drive);
tp_ops->dev_select(drive);
msleep(50);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
(void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0);
......@@ -441,7 +441,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
}
if (drive->dn & 1) {
/* exit with drive0 selected */
SELECT_DRIVE(hwif->devices[0]);
tp_ops->dev_select(hwif->devices[0]);
msleep(50);
/* ensure drive irq is clear */
(void)tp_ops->read_status(hwif);
......@@ -605,6 +605,7 @@ static int ide_register_port(ide_hwif_t *hwif)
static int ide_port_wait_ready(ide_hwif_t *hwif)
{
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
ide_drive_t *drive;
int i, rc;
......@@ -627,8 +628,8 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
/* Ignore disks that we will not probe for later. */
if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 ||
(drive->dev_flags & IDE_DFLAG_PRESENT)) {
SELECT_DRIVE(drive);
hwif->tp_ops->set_irq(hwif, 1);
tp_ops->dev_select(drive);
tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
mdelay(2);
rc = ide_wait_not_busy(hwif, 35000);
if (rc)
......@@ -640,7 +641,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
out:
/* Exit function with master reselected (let's be sane) */
if (i)
SELECT_DRIVE(hwif->devices[0]);
tp_ops->dev_select(hwif->devices[0]);
return rc;
}
......@@ -845,7 +846,7 @@ static int init_irq (ide_hwif_t *hwif)
irq_handler = ide_intr;
if (io_ports->ctl_addr)
hwif->tp_ops->set_irq(hwif, 1);
hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
goto out_up;
......@@ -942,20 +943,16 @@ EXPORT_SYMBOL_GPL(ide_init_disk);
static void drive_release_dev (struct device *dev)
{
ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
ide_hwif_t *hwif = drive->hwif;
ide_proc_unregister_device(drive);
spin_lock_irq(&hwif->lock);
blk_cleanup_queue(drive->queue);
drive->queue = NULL;
kfree(drive->id);
drive->id = NULL;
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
/* Messed up locking ... */
spin_unlock_irq(&hwif->lock);
blk_cleanup_queue(drive->queue);
spin_lock_irq(&hwif->lock);
drive->queue = NULL;
spin_unlock_irq(&hwif->lock);
complete(&drive->gendev_rel_comp);
}
......
......@@ -297,19 +297,15 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
return tape;
}
static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount)
{
struct idetape_bh *bh = pc->bh;
int count;
while (bcount) {
if (bh == NULL) {
printk(KERN_ERR "ide-tape: bh == NULL in "
"idetape_input_buffers\n");
ide_pad_transfer(drive, 0, bcount);
return;
}
if (bh == NULL)
break;
count = min(
(unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
bcount);
......@@ -323,21 +319,21 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
atomic_set(&bh->b_count, 0);
}
}
pc->bh = bh;
return bcount;
}
static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount)
{
struct idetape_bh *bh = pc->bh;
int count;
while (bcount) {
if (bh == NULL) {
printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
__func__);
return;
}
if (bh == NULL)
break;
count = min((unsigned int)pc->b_count, (unsigned int)bcount);
drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
bcount -= count;
......@@ -352,6 +348,8 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
}
}
}
return bcount;
}
static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
......@@ -563,12 +561,14 @@ static void ide_tape_handle_dsc(ide_drive_t *drive)
static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount, int write)
{
unsigned int bleft;
if (write)
idetape_output_buffers(drive, pc, bcount);
bleft = idetape_output_buffers(drive, pc, bcount);
else
idetape_input_buffers(drive, pc, bcount);
bleft = idetape_input_buffers(drive, pc, bcount);
return bcount;
return bcount - bleft;
}
/*
......@@ -2014,9 +2014,13 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc pc;
u8 pc_buf[256];
char fw_rev[4], vendor_id[8], product_id[16];
idetape_create_inquiry_cmd(&pc);
pc.buf = &pc_buf[0];
pc.buf_size = sizeof(pc_buf);
if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
tape->name);
......
......@@ -80,8 +80,14 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
ide_tf_dump(drive->name, tf);
tp_ops->set_irq(hwif, 1);
tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
SELECT_MASK(drive, 0);
if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
u8 data[2] = { tf->data, tf->hob_data };
tp_ops->output_data(drive, cmd, data, 2);
}
tp_ops->tf_load(drive, cmd);
}
......@@ -100,9 +106,7 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE);
return ide_started;
case ATA_PROT_DMA:
if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
ide_build_sglist(drive, cmd) == 0 ||
dma_ops->dma_setup(drive, cmd))
if (ide_dma_prepare(drive, cmd))
return ide_stopped;
hwif->expiry = dma_ops->dma_timer_expiry;
ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD);
......@@ -188,70 +192,68 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
return stat;
}
static void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
unsigned int write, unsigned int nr_bytes)
void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
unsigned int write, unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
struct scatterlist *cursg = cmd->cursg;
struct page *page;
#ifdef CONFIG_HIGHMEM
unsigned long flags;
#endif
unsigned int offset;
u8 *buf;
cursg = cmd->cursg;
if (!cursg) {
cursg = sg;
cmd->cursg = sg;
}
if (cursg == NULL)
cursg = cmd->cursg = sg;
page = sg_page(cursg);
offset = cursg->offset + cmd->cursg_ofs;
while (len) {
unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
/* get the current page and offset */
page = nth_page(page, (offset >> PAGE_SHIFT));
offset %= PAGE_SIZE;
if (nr_bytes > PAGE_SIZE)
nr_bytes = PAGE_SIZE;
#ifdef CONFIG_HIGHMEM
local_irq_save(flags);
#endif
buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
page = sg_page(cursg);
offset = cursg->offset + cmd->cursg_ofs;
cmd->nleft -= nr_bytes;
cmd->cursg_ofs += nr_bytes;
/* get the current page and offset */
page = nth_page(page, (offset >> PAGE_SHIFT));
offset %= PAGE_SIZE;
if (cmd->cursg_ofs == cursg->length) {
cmd->cursg = sg_next(cmd->cursg);
cmd->cursg_ofs = 0;
}
if (PageHighMem(page))
local_irq_save(flags);
/* do the actual data transfer */
if (write)
hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes);
else
hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
kunmap_atomic(buf, KM_BIO_SRC_IRQ);
#ifdef CONFIG_HIGHMEM
local_irq_restore(flags);
#endif
}
cmd->nleft -= nr_bytes;
cmd->cursg_ofs += nr_bytes;
static void ide_pio_multi(ide_drive_t *drive, struct ide_cmd *cmd,
unsigned int write)
{
unsigned int nsect;
if (cmd->cursg_ofs == cursg->length) {
cursg = cmd->cursg = sg_next(cmd->cursg);
cmd->cursg_ofs = 0;
}
/* do the actual data transfer */
if (write)
hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes);
else
hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
kunmap_atomic(buf, KM_BIO_SRC_IRQ);
nsect = min_t(unsigned int, cmd->nleft >> 9, drive->mult_count);
while (nsect--)
ide_pio_bytes(drive, cmd, write, SECTOR_SIZE);
if (PageHighMem(page))
local_irq_restore(flags);
len -= nr_bytes;
}
}
EXPORT_SYMBOL_GPL(ide_pio_bytes);
static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
unsigned int write)
{
unsigned int nr_bytes;
u8 saved_io_32bit = drive->io_32bit;
if (cmd->tf_flags & IDE_TFLAG_FS)
......@@ -263,9 +265,11 @@ static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
touch_softlockup_watchdog();
if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
ide_pio_multi(drive, cmd, write);
nr_bytes = min_t(unsigned, cmd->nleft, drive->mult_count << 9);
else
ide_pio_bytes(drive, cmd, write, SECTOR_SIZE);
nr_bytes = SECTOR_SIZE;
ide_pio_bytes(drive, cmd, write, nr_bytes);
drive->io_32bit = saved_io_32bit;
}
......
......@@ -43,6 +43,8 @@ static struct ide_timing ide_timing[] = {
{ XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 },
{ XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 },
{ XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 80, 0 },
{ XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 100, 0 },
{ XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 },
{ XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 },
{ XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 },
......@@ -51,7 +53,8 @@ static struct ide_timing ide_timing[] = {
{ XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 },
{ XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 },
{ XFER_PIO_5, 20, 50, 30, 100, 50, 30, 100, 0 },
{ XFER_PIO_6, 10, 55, 20, 80, 55, 20, 80, 0 },
{ XFER_PIO_5, 15, 65, 25, 100, 65, 25, 100, 0 },
{ XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 },
{ XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 },
......@@ -90,6 +93,10 @@ u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio)
/* conservative "downgrade" for all pre-ATA2 drives */
if (pio < 3 && cycle < t->cycle)
cycle = 0; /* use standard timing */
/* Use the standard timing for the CF specific modes too */
if (pio > 4 && ata_id_is_cfa(id))
cycle = 0;
}
return cycle ? cycle : t->cycle;
......@@ -161,7 +168,8 @@ int ide_timing_compute(ide_drive_t *drive, u8 speed,
if (speed <= XFER_PIO_2)
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
else if (speed <= XFER_PIO_5)
else if ((speed <= XFER_PIO_4) ||
(speed == XFER_PIO_5 && !ata_id_is_cfa(id)))
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY];
else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
p.cycle = id[ATA_ID_EIDE_DMA_MIN];
......
......@@ -9,11 +9,11 @@ static const char *udma_str[] =
{ "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
"UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
static const char *mwdma_str[] =
{ "MWDMA0", "MWDMA1", "MWDMA2" };
{ "MWDMA0", "MWDMA1", "MWDMA2", "MWDMA3", "MWDMA4" };
static const char *swdma_str[] =
{ "SWDMA0", "SWDMA1", "SWDMA2" };
static const char *pio_str[] =
{ "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
{ "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5", "PIO6" };
/**
* ide_xfer_verbose - return IDE mode names
......@@ -30,11 +30,11 @@ const char *ide_xfer_verbose(u8 mode)
if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
s = udma_str[i];
else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_4)
s = mwdma_str[i];
else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
s = swdma_str[i];
else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_6)
s = pio_str[i & 0x7];
else if (mode == XFER_PIO_SLOW)
s = "PIO SLOW";
......@@ -79,7 +79,10 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
}
if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */
if (ata_id_has_iordy(id)) {
if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 7))
pio_mode = 4 + min_t(int, 2,
id[ATA_ID_CFA_MODES] & 7);
else if (ata_id_has_iordy(id)) {
if (id[ATA_ID_PIO_MODES] & 7) {
overridden = 0;
if (id[ATA_ID_PIO_MODES] & 4)
......@@ -239,7 +242,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
BUG_ON(rate < XFER_PIO_0);
if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
if (rate >= XFER_PIO_0 && rate <= XFER_PIO_6)
return ide_set_pio_mode(drive, rate);
return ide_set_dma_mode(drive, rate);
......
/*
* ARM default IDE host driver
*
* Copyright (C) 2004 Bartlomiej Zolnierkiewicz
* Based on code by: Russell King, Ian Molton and Alexander Schulz.
*
* May be copied or modified under the terms of the GNU General Public License.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ide.h>
#include <asm/irq.h>
#define DRV_NAME "ide_arm"
#define IDE_ARM_IO 0x1f0
#define IDE_ARM_IRQ IRQ_HARDDISK
static const struct ide_port_info ide_arm_port_info = {
.host_flags = IDE_HFLAG_NO_DMA,
};
static int __init ide_arm_init(void)
{
unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206;
hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
if (!request_region(base, 8, DRV_NAME)) {
printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
DRV_NAME, base, base + 7);
return -EBUSY;
}
if (!request_region(ctl, 1, DRV_NAME)) {
printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
DRV_NAME, ctl);
release_region(base, 8);
return -EBUSY;
}
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, base, ctl);
hw.irq = IDE_ARM_IRQ;
hw.chipset = ide_generic;
return ide_host_add(&ide_arm_port_info, hws, NULL);
}
module_init(ide_arm_init);
MODULE_LICENSE("GPL");
......@@ -511,9 +511,8 @@ static struct ide_dma_ops it821x_pass_through_dma_ops = {
.dma_start = it821x_dma_start,
.dma_end = it821x_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......
......@@ -66,18 +66,11 @@ static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u16 data = inw(io_ports->data_addr);
tf->data = data & 0xff;
tf->hob_data = (data >> 8) & 0xff;
}
/* be sure we're looking at the low order bits */
outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
tf->error = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
......@@ -90,28 +83,30 @@ static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = superio_ide_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
tf->hob_error = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = inb(io_ports->nsect_addr);
tf->hob_nsect = inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = inb(io_ports->lbal_addr);
tf->hob_lbal = inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = inb(io_ports->lbam_addr);
tf->hob_lbam = inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = inb(io_ports->lbah_addr);
tf->hob_lbah = inb(io_ports->lbah_addr);
}
}
static void ns87415_dev_select(ide_drive_t *drive);
static const struct ide_tp_ops superio_tp_ops = {
.exec_command = ide_exec_command,
.read_status = superio_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.set_irq = ide_set_irq,
.dev_select = ns87415_dev_select,
.tf_load = ide_tf_load,
.tf_read = superio_tf_read,
......@@ -190,10 +185,18 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
local_irq_restore(flags);
}
static void ns87415_selectproc (ide_drive_t *drive)
static void ns87415_dev_select(ide_drive_t *drive)
{
ns87415_prepare_drive(drive,
!!(drive->dev_flags & IDE_DFLAG_USING_DMA));
outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
}
static void ns87415_dma_start(ide_drive_t *drive)
{
ns87415_prepare_drive(drive, 1);
ide_dma_start(drive);
}
static int ns87415_dma_end(ide_drive_t *drive)
......@@ -201,7 +204,6 @@ static int ns87415_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
drive->waiting_for_dma = 0;
dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
/* get DMA command mode */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
......@@ -210,21 +212,11 @@ static int ns87415_dma_end(ide_drive_t *drive)
/* from ERRATA: clear the INTR & ERROR bits */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
outb(dma_cmd | 6, hwif->dma_base + ATA_DMA_CMD);
/* and free any DMA resources */
ide_destroy_dmatable(drive);
/* verify good DMA status */
return (dma_stat & 7) != 4;
}
static int ns87415_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
/* select DMA xfer */
ns87415_prepare_drive(drive, 1);
if (ide_dma_setup(drive, cmd) == 0)
return 0;
/* DMA failed: select PIO xfer */
ns87415_prepare_drive(drive, 0);
return 1;
/* verify good DMA status */
return (dma_stat & 7) != 4;
}
static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
......@@ -242,7 +234,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
* Also, leave IRQ masked during drive probing, to prevent infinite
* interrupts from a potentially floating INTA..
*
* IRQs get unmasked in selectproc when drive is first used.
* IRQs get unmasked in dev_select() when drive is first used.
*/
(void) pci_read_config_dword(dev, 0x40, &ctrl);
(void) pci_read_config_byte(dev, 0x09, &progif);
......@@ -270,7 +262,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
#ifdef __sparc_v9__
/*
* XXX: Reset the device, if we don't it will not respond to
* SELECT_DRIVE() properly during first ide_probe_port().
* dev_select() properly during first ide_probe_port().
*/
timeout = 10000;
outb(12, hwif->io_ports.ctl_addr);
......@@ -294,26 +286,35 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
outb(0x60, hwif->dma_base + ATA_DMA_STATUS);
}
static const struct ide_port_ops ns87415_port_ops = {
.selectproc = ns87415_selectproc,
static const struct ide_tp_ops ns87415_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.dev_select = ns87415_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
.input_data = ide_input_data,
.output_data = ide_output_data,
};
static const struct ide_dma_ops ns87415_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ns87415_dma_setup,
.dma_start = ide_dma_start,
.dma_setup = ide_dma_setup,
.dma_start = ns87415_dma_start,
.dma_end = ns87415_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_sff_read_status = superio_dma_sff_read_status,
};
static const struct ide_port_info ns87415_chipset __devinitdata = {
.name = DRV_NAME,
.init_hwif = init_hwif_ns87415,
.port_ops = &ns87415_port_ops,
.tp_ops = &ns87415_tp_ops,
.dma_ops = &ns87415_dma_ops,
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_NO_ATAPI_DMA,
......
......@@ -258,12 +258,6 @@ static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
ide_dma_lost_irq(drive);
}
static void pdc202xx_dma_timeout(ide_drive_t *drive)
{
pdc202xx_reset(drive);
ide_dma_timeout(drive);
}
static int init_chipset_pdc202xx(struct pci_dev *dev)
{
unsigned long dmabase = pci_resource_start(dev, 4);
......@@ -336,7 +330,7 @@ static const struct ide_dma_ops pdc20246_dma_ops = {
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = pdc202xx_dma_timeout,
.dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......@@ -348,7 +342,7 @@ static const struct ide_dma_ops pdc2026x_dma_ops = {
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = pdc202xx_dma_timeout,
.dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......
......@@ -404,8 +404,6 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
#define IDE_WAKEUP_DELAY (1*HZ)
static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
static void pmac_ide_selectproc(ide_drive_t *drive);
static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
#define PMAC_IDE_REG(x) \
((void __iomem *)((drive)->hwif->io_ports.data_addr + (x)))
......@@ -415,8 +413,7 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
* timing register when selecting that unit. This version is for
* ASICs with a single timing register
*/
static void
pmac_ide_selectproc(ide_drive_t *drive)
static void pmac_ide_apply_timings(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
......@@ -434,8 +431,7 @@ pmac_ide_selectproc(ide_drive_t *drive)
* timing register when selecting that unit. This version is for
* ASICs with a dual timing register (Kauai)
*/
static void
pmac_ide_kauai_selectproc(ide_drive_t *drive)
static void pmac_ide_kauai_apply_timings(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
......@@ -464,9 +460,25 @@ pmac_ide_do_update_timings(ide_drive_t *drive)
if (pmif->kind == controller_sh_ata6 ||
pmif->kind == controller_un_ata6 ||
pmif->kind == controller_k2_ata6)
pmac_ide_kauai_selectproc(drive);
pmac_ide_kauai_apply_timings(drive);
else
pmac_ide_selectproc(drive);
pmac_ide_apply_timings(drive);
}
static void pmac_dev_select(ide_drive_t *drive)
{
pmac_ide_apply_timings(drive);
writeb(drive->select | ATA_DEVICE_OBS,
(void __iomem *)drive->hwif->io_ports.device_addr);
}
static void pmac_kauai_dev_select(ide_drive_t *drive)
{
pmac_ide_kauai_apply_timings(drive);
writeb(drive->select | ATA_DEVICE_OBS,
(void __iomem *)drive->hwif->io_ports.device_addr);
}
static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd)
......@@ -476,17 +488,8 @@ static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd)
+ IDE_TIMING_CONFIG));
}
static void pmac_set_irq(ide_hwif_t *hwif, int on)
static void pmac_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
u8 ctl = ATA_DEVCTL_OBS;
if (on == 4) { /* hack for SRST */
ctl |= 4;
on &= ~4;
}
ctl |= on ? 0 : 2;
writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
(void)readl((void __iomem *)(hwif->io_ports.data_addr
+ IDE_TIMING_CONFIG));
......@@ -916,10 +919,18 @@ static u8 pmac_ide_cable_detect(ide_hwif_t *hwif)
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
struct device_node *np = pmif->node;
const char *cable = of_get_property(np, "cable-type", NULL);
struct device_node *root = of_find_node_by_path("/");
const char *model = of_get_property(root, "model", NULL);
/* Get cable type from device-tree. */
if (cable && !strncmp(cable, "80-", 3))
return ATA_CBL_PATA80;
if (cable && !strncmp(cable, "80-", 3)) {
/* Some drives fail to detect 80c cable in PowerBook */
/* These machine use proprietary short IDE cable anyway */
if (!strncmp(model, "PowerBook", 9))
return ATA_CBL_PATA40_SHORT;
else
return ATA_CBL_PATA80;
}
/*
* G5's seem to have incorrect cable type in device-tree.
......@@ -954,9 +965,9 @@ static const struct ide_tp_ops pmac_tp_ops = {
.exec_command = pmac_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = pmac_write_devctl,
.set_irq = pmac_set_irq,
.dev_select = pmac_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
......@@ -964,19 +975,24 @@ static const struct ide_tp_ops pmac_tp_ops = {
.output_data = ide_output_data,
};
static const struct ide_port_ops pmac_ide_ata6_port_ops = {
.init_dev = pmac_ide_init_dev,
.set_pio_mode = pmac_ide_set_pio_mode,
.set_dma_mode = pmac_ide_set_dma_mode,
.selectproc = pmac_ide_kauai_selectproc,
.cable_detect = pmac_ide_cable_detect,
static const struct ide_tp_ops pmac_ata6_tp_ops = {
.exec_command = pmac_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = pmac_write_devctl,
.dev_select = pmac_kauai_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
.input_data = ide_input_data,
.output_data = ide_output_data,
};
static const struct ide_port_ops pmac_ide_ata4_port_ops = {
.init_dev = pmac_ide_init_dev,
.set_pio_mode = pmac_ide_set_pio_mode,
.set_dma_mode = pmac_ide_set_dma_mode,
.selectproc = pmac_ide_selectproc,
.cable_detect = pmac_ide_cable_detect,
};
......@@ -984,7 +1000,6 @@ static const struct ide_port_ops pmac_ide_port_ops = {
.init_dev = pmac_ide_init_dev,
.set_pio_mode = pmac_ide_set_pio_mode,
.set_dma_mode = pmac_ide_set_dma_mode,
.selectproc = pmac_ide_selectproc,
};
static const struct ide_dma_ops pmac_dma_ops;
......@@ -1021,15 +1036,18 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw)
pmif->broken_dma = pmif->broken_dma_warn = 0;
if (of_device_is_compatible(np, "shasta-ata")) {
pmif->kind = controller_sh_ata6;
d.port_ops = &pmac_ide_ata6_port_ops;
d.tp_ops = &pmac_ata6_tp_ops;
d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA6;
} else if (of_device_is_compatible(np, "kauai-ata")) {
pmif->kind = controller_un_ata6;
d.port_ops = &pmac_ide_ata6_port_ops;
d.tp_ops = &pmac_ata6_tp_ops;
d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA5;
} else if (of_device_is_compatible(np, "K2-UATA")) {
pmif->kind = controller_k2_ata6;
d.port_ops = &pmac_ide_ata6_port_ops;
d.tp_ops = &pmac_ata6_tp_ops;
d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA5;
} else if (of_device_is_compatible(np, "keylargo-ata")) {
if (strcmp(np->name, "ata-4") == 0) {
......@@ -1455,7 +1473,7 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
"switching to PIO on Ohare chipset\n", drive->name);
pmif->broken_dma_warn = 1;
}
goto use_pio_instead;
return 0;
}
while (cur_len) {
unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
......@@ -1463,7 +1481,7 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
if (count++ >= MAX_DCMDS) {
printk(KERN_WARNING "%s: DMA table too small\n",
drive->name);
goto use_pio_instead;
return 0;
}
st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE);
st_le16(&table->req_count, tc);
......@@ -1492,9 +1510,6 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
use_pio_instead:
ide_destroy_dmatable(drive);
return 0; /* revert to PIO for this request */
}
......@@ -1510,10 +1525,8 @@ static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
if (pmac_ide_build_dmatable(drive, cmd) == 0) {
ide_map_sg(drive, cmd);
if (pmac_ide_build_dmatable(drive, cmd) == 0)
return 1;
}
/* Apple adds 60ns to wrDataSetup on reads */
if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
......@@ -1522,8 +1535,6 @@ static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
(void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
}
drive->waiting_for_dma = 1;
return 0;
}
......@@ -1558,12 +1569,9 @@ pmac_ide_dma_end (ide_drive_t *drive)
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
u32 dstat;
drive->waiting_for_dma = 0;
dstat = readl(&dma->status);
writel(((RUN|WAKE|DEAD) << 16), &dma->control);
ide_destroy_dmatable(drive);
/* verify good dma status. we don't check for ACTIVE beeing 0. We should...
* in theory, but with ATAPI decices doing buffer underruns, that would
* cause us to disable DMA, which isn't what we want
......@@ -1650,7 +1658,6 @@ static const struct ide_dma_ops pmac_dma_ops = {
.dma_start = pmac_ide_dma_start,
.dma_end = pmac_ide_dma_end,
.dma_test_irq = pmac_ide_dma_test_irq,
.dma_timeout = ide_dma_timeout,
.dma_lost_irq = pmac_ide_dma_lost_irq,
};
......
......@@ -99,9 +99,9 @@ static const struct ide_tp_ops q40ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.set_irq = ide_set_irq,
.dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
......
......@@ -90,13 +90,15 @@ static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
* This routine is invoked to prepare for access to a given drive.
*/
static void qd65xx_select(ide_drive_t *drive)
static void qd65xx_dev_select(ide_drive_t *drive)
{
u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) |
(QD_TIMREG(drive) & 0x02);
if (timings[index] != QD_TIMING(drive))
outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
}
/*
......@@ -309,20 +311,33 @@ static void __init qd6580_init_dev(ide_drive_t *drive)
drive->drive_data = (drive->dn & 1) ? t2 : t1;
}
static const struct ide_tp_ops qd65xx_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.dev_select = qd65xx_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
.input_data = ide_input_data,
.output_data = ide_output_data,
};
static const struct ide_port_ops qd6500_port_ops = {
.init_dev = qd6500_init_dev,
.set_pio_mode = qd6500_set_pio_mode,
.selectproc = qd65xx_select,
};
static const struct ide_port_ops qd6580_port_ops = {
.init_dev = qd6580_init_dev,
.set_pio_mode = qd6580_set_pio_mode,
.selectproc = qd65xx_select,
};
static const struct ide_port_info qd65xx_port_info __initdata = {
.name = DRV_NAME,
.tp_ops = &qd65xx_tp_ops,
.chipset = ide_qd65xx,
.host_flags = IDE_HFLAG_IO_32BIT |
IDE_HFLAG_NO_DMA,
......
......@@ -115,8 +115,7 @@ static u8 sc1200_udma_filter(ide_drive_t *drive)
if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
(mateid[ATA_ID_UDMA_MODES] & 7))
goto out;
if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
(mateid[ATA_ID_MWDMA_MODES] & 7))
if (mateid[ATA_ID_MWDMA_MODES] & 7)
mask = 0;
}
out:
......@@ -183,9 +182,6 @@ static int sc1200_dma_end(ide_drive_t *drive)
outb(dma_stat|0x1b, dma_base+2); /* clear the INTR & ERROR bits */
outb(inb(dma_base)&~1, dma_base); /* !! DO THIS HERE !! stop DMA */
drive->waiting_for_dma = 0;
ide_destroy_dmatable(drive); /* purge DMA mappings */
return (dma_stat & 7) != 4; /* verify good DMA status */
}
......@@ -291,7 +287,6 @@ static const struct ide_dma_ops sc1200_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......
......@@ -148,17 +148,8 @@ static u8 scc_dma_sff_read_status(ide_hwif_t *hwif)
return (u8)in_be32((void *)(hwif->dma_base + 4));
}
static void scc_set_irq(ide_hwif_t *hwif, int on)
static void scc_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
u8 ctl = ATA_DEVCTL_OBS;
if (on == 4) { /* hack for SRST */
ctl |= 4;
on &= ~4;
}
ctl |= on ? 0 : 2;
out_be32((void *)hwif->io_ports.ctl_addr, ctl);
eieio();
in_be32((void *)(hwif->dma_base + 0x01c));
......@@ -321,10 +312,8 @@ static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
u8 dma_stat;
/* fall back to pio! */
if (ide_build_dmatable(drive, cmd) == 0) {
ide_map_sg(drive, cmd);
if (ide_build_dmatable(drive, cmd) == 0)
return 1;
}
/* PRD table */
out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma);
......@@ -337,7 +326,7 @@ static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
/* clear INTR & ERROR flags */
out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6);
drive->waiting_for_dma = 1;
return 0;
}
......@@ -356,7 +345,6 @@ static int __scc_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat, dma_cmd;
drive->waiting_for_dma = 0;
/* get DMA command mode */
dma_cmd = scc_ide_inb(hwif->dma_base);
/* stop DMA */
......@@ -365,8 +353,6 @@ static int __scc_dma_end(ide_drive_t *drive)
dma_stat = scc_dma_sff_read_status(hwif);
/* clear the INTR & ERROR bits */
scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
/* purge DMA mappings */
ide_destroy_dmatable(drive);
/* verify good DMA status */
wmb();
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
......@@ -670,10 +656,6 @@ static void scc_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA)
out_be32((void *)io_ports->data_addr,
(tf->hob_data << 8) | tf->data);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
scc_ide_outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
......@@ -706,18 +688,11 @@ static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u16 data = (u16)in_be32((void *)io_ports->data_addr);
tf->data = data & 0xff;
tf->hob_data = (data >> 8) & 0xff;
}
/* be sure we're looking at the low order bits */
scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
scc_ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = scc_ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
tf->error = scc_ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = scc_ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
......@@ -730,18 +705,18 @@ static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = scc_ide_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
scc_ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = scc_ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
tf->hob_error = scc_ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr);
tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr);
tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr);
tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr);
}
}
......@@ -848,9 +823,9 @@ static const struct ide_tp_ops scc_tp_ops = {
.exec_command = scc_exec_command,
.read_status = scc_read_status,
.read_altstatus = scc_read_altstatus,
.write_devctl = scc_write_devctl,
.set_irq = scc_set_irq,
.dev_select = ide_dev_select,
.tf_load = scc_tf_load,
.tf_read = scc_tf_read,
......@@ -872,7 +847,6 @@ static const struct ide_dma_ops scc_dma_ops = {
.dma_end = scc_dma_end,
.dma_test_irq = scc_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = scc_dma_sff_read_status,
};
......
......@@ -258,9 +258,6 @@ static int sgiioc4_dma_end(ide_drive_t *drive)
}
}
drive->waiting_for_dma = 0;
ide_destroy_dmatable(drive);
return dma_stat;
}
......@@ -280,10 +277,12 @@ static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
sgiioc4_clearirq(drive);
}
static void
sgiioc4_resetproc(ide_drive_t * drive)
static void sgiioc4_resetproc(ide_drive_t *drive)
{
struct ide_cmd *cmd = &drive->hwif->cmd;
sgiioc4_dma_end(drive);
ide_dma_unmap_sg(drive, cmd);
sgiioc4_clearirq(drive);
}
......@@ -412,7 +411,6 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
writel(dma_direction, (void __iomem *)ioc4_dma_addr);
drive->waiting_for_dma = 1;
}
/* IOC4 Scatter Gather list Format */
......@@ -442,7 +440,7 @@ static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
printk(KERN_WARNING
"%s: DMA table too small\n",
drive->name);
goto use_pio_instead;
return 0;
} else {
u32 bcount =
0x10000 - (cur_addr & 0xffff);
......@@ -477,9 +475,6 @@ static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
return count;
}
use_pio_instead:
ide_destroy_dmatable(drive);
return 0; /* revert to PIO for this request */
}
......@@ -488,11 +483,9 @@ static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
int ddir;
u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
if (sgiioc4_build_dmatable(drive, cmd) == 0) {
if (sgiioc4_build_dmatable(drive, cmd) == 0)
/* try PIO instead of DMA */
ide_map_sg(drive, cmd);
return 1;
}
if (write)
/* Writes TO the IOC4 FROM Main Memory */
......@@ -510,9 +503,9 @@ static const struct ide_tp_ops sgiioc4_tp_ops = {
.exec_command = ide_exec_command,
.read_status = sgiioc4_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.set_irq = ide_set_irq,
.dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
......@@ -533,7 +526,6 @@ static const struct ide_dma_ops sgiioc4_dma_ops = {
.dma_end = sgiioc4_dma_end,
.dma_test_irq = sgiioc4_dma_test_irq,
.dma_lost_irq = sgiioc4_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
};
static const struct ide_port_info sgiioc4_port_info __devinitconst = {
......
......@@ -715,7 +715,6 @@ static const struct ide_dma_ops sil_dma_ops = {
.dma_end = ide_dma_end,
.dma_test_irq = siimage_dma_test_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......
......@@ -61,7 +61,8 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
if (cmd_off == 0)
cmd_off = 1;
if (pio > 2 || ata_id_has_iordy(drive->id))
if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
!(pio > 4 && ata_id_is_cfa(drive->id)))
iordy = 0x40;
return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy;
......@@ -189,14 +190,13 @@ static void sl82c105_dma_start(ide_drive_t *drive)
ide_dma_start(drive);
}
static void sl82c105_dma_timeout(ide_drive_t *drive)
static void sl82c105_dma_clear(ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
DBG(("sl82c105_dma_timeout(drive:%s)\n", drive->name));
DBG(("sl82c105_dma_clear(drive:%s)\n", drive->name));
sl82c105_reset_host(dev);
ide_dma_timeout(drive);
}
static int sl82c105_dma_end(ide_drive_t *drive)
......@@ -298,7 +298,7 @@ static const struct ide_dma_ops sl82c105_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = sl82c105_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = sl82c105_dma_timeout,
.dma_clear = sl82c105_dma_clear,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......
......@@ -187,7 +187,6 @@ static const struct ide_dma_ops tc86c001_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
......
......@@ -171,54 +171,51 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
local_irq_restore(flags);
}
static void trm290_selectproc (ide_drive_t *drive)
static void trm290_dev_select(ide_drive_t *drive)
{
trm290_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA));
outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
}
static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
static int trm290_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
unsigned int count, rw;
if (cmd->tf_flags & IDE_TFLAG_WRITE) {
#ifdef TRM290_NO_DMA_WRITES
/* always use PIO for writes */
trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
#endif
rw = 1;
} else
rw = 2;
}
return 0;
}
static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
unsigned int count, rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 2;
count = ide_build_dmatable(drive, cmd);
if (count == 0) {
ide_map_sg(drive, cmd);
if (count == 0)
/* try PIO instead of DMA */
trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
}
/* select DMA xfer */
trm290_prepare_drive(drive, 1);
outl(hwif->dmatable_dma | rw, hwif->dma_base);
drive->waiting_for_dma = 1;
/* start DMA */
outw(count * 2 - 1, hwif->dma_base + 2);
return 0;
}
static void trm290_dma_start(ide_drive_t *drive)
{
trm290_prepare_drive(drive, 1);
}
static int trm290_dma_end(ide_drive_t *drive)
{
u16 status;
u16 status = inw(drive->hwif->dma_base + 2);
drive->waiting_for_dma = 0;
/* purge DMA mappings */
ide_destroy_dmatable(drive);
status = inw(drive->hwif->dma_base + 2);
trm290_prepare_drive(drive, 0);
return status != 0x00ff;
}
......@@ -303,8 +300,18 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
#endif
}
static const struct ide_port_ops trm290_port_ops = {
.selectproc = trm290_selectproc,
static const struct ide_tp_ops trm290_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.dev_select = trm290_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
.input_data = ide_input_data,
.output_data = ide_output_data,
};
static struct ide_dma_ops trm290_dma_ops = {
......@@ -314,13 +321,13 @@ static struct ide_dma_ops trm290_dma_ops = {
.dma_end = trm290_dma_end,
.dma_test_irq = trm290_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
.dma_check = trm290_dma_check,
};
static const struct ide_port_info trm290_chipset __devinitdata = {
.name = DRV_NAME,
.init_hwif = init_hwif_trm290,
.port_ops = &trm290_port_ops,
.tp_ops = &trm290_tp_ops,
.dma_ops = &trm290_dma_ops,
.host_flags = IDE_HFLAG_TRM290 |
IDE_HFLAG_NO_ATAPI_DMA |
......
......@@ -92,13 +92,6 @@ static void tx4938ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
u16 data = (tf->hob_data << 8) | tf->data;
/* no endian swap */
__raw_writew(data, (void __iomem *)io_ports->data_addr);
}
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tx4938ide_outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
......@@ -132,20 +125,11 @@ static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u16 data;
/* no endian swap */
data = __raw_readw((void __iomem *)io_ports->data_addr);
tf->data = data & 0xff;
tf->hob_data = (data >> 8) & 0xff;
}
/* be sure we're looking at the low order bits */
tx4938ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
tx4938ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = tx4938ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
tf->error = tx4938ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tx4938ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
......@@ -158,19 +142,18 @@ static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = tx4938ide_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
tx4938ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
tx4938ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature =
tx4938ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
tf->hob_error = tx4938ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr);
tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr);
tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr);
tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr);
tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr);
}
}
......@@ -204,9 +187,9 @@ static const struct ide_tp_ops tx4938ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.set_irq = ide_set_irq,
.dev_select = ide_dev_select,
.tf_load = tx4938ide_tf_load,
.tf_read = tx4938ide_tf_read,
......
......@@ -279,8 +279,6 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");
ide_destroy_dmatable(drive);
return 0; /* revert to PIO for this request */
}
#else
......@@ -294,10 +292,8 @@ static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
/* fall back to PIO! */
if (tx4939ide_build_dmatable(drive, cmd) == 0) {
ide_map_sg(drive, cmd);
if (tx4939ide_build_dmatable(drive, cmd) == 0)
return 1;
}
/* PRD table */
tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr);
......@@ -308,8 +304,6 @@ static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
/* clear INTR & ERROR flags */
tx4939ide_clear_dma_status(base);
drive->waiting_for_dma = 1;
tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ?
TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1);
......@@ -325,8 +319,6 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
void __iomem *base = TX4939IDE_BASE(hwif);
u16 ctl = tx4939ide_readw(base, TX4939IDE_Int_Ctl);
drive->waiting_for_dma = 0;
/* get DMA command mode */
dma_cmd = tx4939ide_readb(base, TX4939IDE_DMA_Cmd);
/* stop DMA */
......@@ -335,11 +327,9 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
/* read and clear the INTR & ERROR bits */
dma_stat = tx4939ide_clear_dma_status(base);
/* purge DMA mappings */
ide_destroy_dmatable(drive);
/* verify good DMA status */
wmb();
/* verify good DMA status */
if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 &&
(ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) ==
(TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST))
......@@ -439,7 +429,7 @@ static void tx4939ide_tf_load_fixup(ide_drive_t *drive)
* Fix ATA100 CORE System Control Register. (The write to the
* Device/Head register may write wrong data to the System
* Control Register)
* While Sys_Ctl is written here, selectproc is not needed.
* While Sys_Ctl is written here, dev_select() is not needed.
*/
tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl);
}
......@@ -467,13 +457,6 @@ static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
u16 data = (tf->hob_data << 8) | tf->data;
/* no endian swap */
__raw_writew(data, (void __iomem *)io_ports->data_addr);
}
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tx4939ide_outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
......@@ -509,20 +492,11 @@ static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u16 data;
/* no endian swap */
data = __raw_readw((void __iomem *)io_ports->data_addr);
tf->data = data & 0xff;
tf->hob_data = (data >> 8) & 0xff;
}
/* be sure we're looking at the low order bits */
tx4939ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
tx4939ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = tx4939ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
tf->error = tx4939ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tx4939ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
......@@ -535,19 +509,18 @@ static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = tx4939ide_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
tx4939ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
tx4939ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature =
tx4939ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
tf->hob_error = tx4939ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr);
tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr);
tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr);
tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr);
}
}
......@@ -581,9 +554,9 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.set_irq = ide_set_irq,
.dev_select = ide_dev_select,
.tf_load = tx4939ide_tf_load,
.tf_read = tx4939ide_tf_read,
......@@ -605,9 +578,9 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.set_irq = ide_set_irq,
.dev_select = ide_dev_select,
.tf_load = tx4939ide_tf_load,
.tf_read = ide_tf_read,
......@@ -632,7 +605,6 @@ static const struct ide_dma_ops tx4939ide_dma_ops = {
.dma_test_irq = tx4939ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_timeout = ide_dma_timeout,
.dma_sff_read_status = tx4939ide_dma_sff_read_status,
};
......
......@@ -265,7 +265,7 @@ enum {
IDE_TFLAG_WRITE = (1 << 12),
IDE_TFLAG_CUSTOM_HANDLER = (1 << 13),
IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 14),
IDE_TFLAG_IN_HOB_FEATURE = (1 << 15),
IDE_TFLAG_IN_HOB_ERROR = (1 << 15),
IDE_TFLAG_IN_HOB_NSECT = (1 << 16),
IDE_TFLAG_IN_HOB_LBAL = (1 << 17),
IDE_TFLAG_IN_HOB_LBAM = (1 << 18),
......@@ -273,10 +273,10 @@ enum {
IDE_TFLAG_IN_HOB_LBA = IDE_TFLAG_IN_HOB_LBAL |
IDE_TFLAG_IN_HOB_LBAM |
IDE_TFLAG_IN_HOB_LBAH,
IDE_TFLAG_IN_HOB = IDE_TFLAG_IN_HOB_FEATURE |
IDE_TFLAG_IN_HOB = IDE_TFLAG_IN_HOB_ERROR |
IDE_TFLAG_IN_HOB_NSECT |
IDE_TFLAG_IN_HOB_LBA,
IDE_TFLAG_IN_FEATURE = (1 << 20),
IDE_TFLAG_IN_ERROR = (1 << 20),
IDE_TFLAG_IN_NSECT = (1 << 21),
IDE_TFLAG_IN_LBAL = (1 << 22),
IDE_TFLAG_IN_LBAM = (1 << 23),
......@@ -310,8 +310,12 @@ enum {
struct ide_taskfile {
u8 hob_data; /* 0: high data byte (for TASKFILE IOCTL) */
/* 1-5: additional data to support LBA48 */
union {
u8 hob_error; /* read: error */
u8 hob_feature; /* write: feature */
};
u8 hob_feature; /* 1-5: additional data to support LBA48 */
u8 hob_nsect;
u8 hob_lbal;
u8 hob_lbam;
......@@ -352,6 +356,8 @@ struct ide_cmd {
unsigned int nbytes;
unsigned int nleft;
unsigned int last_xfer_len;
struct scatterlist *cursg;
unsigned int cursg_ofs;
......@@ -375,7 +381,7 @@ enum {
* With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes.
* This is used for several packet commands (not for READ/WRITE commands).
*/
#define IDE_PC_BUFFER_SIZE 256
#define IDE_PC_BUFFER_SIZE 64
#define ATAPI_WAIT_PC (60 * HZ)
struct ide_atapi_pc {
......@@ -413,9 +419,6 @@ struct ide_atapi_pc {
struct idetape_bh *bh;
char *b_data;
struct scatterlist *sg;
unsigned int sg_cnt;
unsigned long timeout;
};
......@@ -456,11 +459,6 @@ enum {
IDE_AFLAG_TOCADDR_AS_BCD = (1 << 3),
/* TOC track numbers are in BCD. */
IDE_AFLAG_TOCTRACKS_AS_BCD = (1 << 4),
/*
* Drive does not provide data in multiples of SECTOR_SIZE
* when more than one interrupt is needed.
*/
IDE_AFLAG_LIMIT_NFRAMES = (1 << 5),
/* Saved TOC information is current. */
IDE_AFLAG_TOC_VALID = (1 << 6),
/* We think that the drive door is locked. */
......@@ -605,7 +603,7 @@ struct ide_drive_s {
unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */
unsigned int cyl; /* "real" number of cyls */
unsigned int drive_data; /* used by set_pio_mode/selectproc */
unsigned int drive_data; /* used by set_pio_mode/dev_select() */
unsigned int failures; /* current failure count */
unsigned int max_failures; /* maximum allowed failure count */
u64 probed_capacity;/* initial reported media capacity (ide-cd only currently) */
......@@ -661,9 +659,9 @@ struct ide_tp_ops {
void (*exec_command)(struct hwif_s *, u8);
u8 (*read_status)(struct hwif_s *);
u8 (*read_altstatus)(struct hwif_s *);
void (*write_devctl)(struct hwif_s *, u8);
void (*set_irq)(struct hwif_s *, int);
void (*dev_select)(ide_drive_t *);
void (*tf_load)(ide_drive_t *, struct ide_cmd *);
void (*tf_read)(ide_drive_t *, struct ide_cmd *);
......@@ -681,7 +679,6 @@ extern const struct ide_tp_ops default_tp_ops;
* @init_dev: host specific initialization of a device
* @set_pio_mode: routine to program host for PIO mode
* @set_dma_mode: routine to program host for DMA mode
* @selectproc: tweaks hardware to select drive
* @reset_poll: chipset polling based on hba specifics
* @pre_reset: chipset specific changes to default for device-hba resets
* @resetproc: routine to reset controller after a disk reset
......@@ -698,7 +695,6 @@ struct ide_port_ops {
void (*init_dev)(ide_drive_t *);
void (*set_pio_mode)(ide_drive_t *, const u8);
void (*set_dma_mode)(ide_drive_t *, const u8);
void (*selectproc)(ide_drive_t *);
int (*reset_poll)(ide_drive_t *);
void (*pre_reset)(ide_drive_t *);
void (*resetproc)(ide_drive_t *);
......@@ -719,8 +715,10 @@ struct ide_dma_ops {
int (*dma_end)(struct ide_drive_s *);
int (*dma_test_irq)(struct ide_drive_s *);
void (*dma_lost_irq)(struct ide_drive_s *);
/* below ones are optional */
int (*dma_check)(struct ide_drive_s *, struct ide_cmd *);
int (*dma_timer_expiry)(struct ide_drive_s *);
void (*dma_timeout)(struct ide_drive_s *);
void (*dma_clear)(struct ide_drive_s *);
/*
* The following method is optional and only required to be
* implemented for the SFF-8038i compatible controllers.
......@@ -1169,18 +1167,15 @@ void ide_tf_dump(const char *, struct ide_taskfile *);
void ide_exec_command(ide_hwif_t *, u8);
u8 ide_read_status(ide_hwif_t *);
u8 ide_read_altstatus(ide_hwif_t *);
void ide_write_devctl(ide_hwif_t *, u8);
void ide_set_irq(ide_hwif_t *, int);
void ide_dev_select(ide_drive_t *);
void ide_tf_load(ide_drive_t *, struct ide_cmd *);
void ide_tf_read(ide_drive_t *, struct ide_cmd *);
void ide_input_data(ide_drive_t *, struct ide_cmd *, void *, unsigned int);
void ide_output_data(ide_drive_t *, struct ide_cmd *, void *, unsigned int);
int ide_io_buffers(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int);
extern void SELECT_DRIVE(ide_drive_t *);
void SELECT_MASK(ide_drive_t *, int);
u8 ide_read_error(ide_drive_t *);
......@@ -1226,6 +1221,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_cmd *);
ide_startstop_t do_rw_taskfile(ide_drive_t *, struct ide_cmd *);
void ide_pio_bytes(ide_drive_t *, struct ide_cmd *, unsigned int, unsigned int);
void ide_finish_cmd(ide_drive_t *, struct ide_cmd *, u8);
int ide_raw_taskfile(ide_drive_t *, struct ide_cmd *, u8 *, u16);
......@@ -1443,8 +1440,8 @@ ide_startstop_t ide_dma_intr(ide_drive_t *);
int ide_allocate_dma_engine(ide_hwif_t *);
void ide_release_dma_engine(ide_hwif_t *);
int ide_build_sglist(ide_drive_t *, struct ide_cmd *);
void ide_destroy_dmatable(ide_drive_t *);
int ide_dma_prepare(ide_drive_t *, struct ide_cmd *);
void ide_dma_unmap_sg(ide_drive_t *, struct ide_cmd *);
#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
int config_drive_for_dma(ide_drive_t *);
......@@ -1462,7 +1459,6 @@ static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
void ide_dma_lost_irq(ide_drive_t *);
void ide_dma_timeout(ide_drive_t *);
ide_startstop_t ide_dma_timeout_retry(ide_drive_t *, int);
#else
......@@ -1478,8 +1474,10 @@ static inline void ide_check_dma_crc(ide_drive_t *drive) { ; }
static inline ide_startstop_t ide_dma_intr(ide_drive_t *drive) { return ide_stopped; }
static inline ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) { return ide_stopped; }
static inline void ide_release_dma_engine(ide_hwif_t *hwif) { ; }
static inline int ide_build_sglist(ide_drive_t *drive,
struct ide_cmd *cmd) { return 0; }
static inline int ide_dma_prepare(ide_drive_t *drive,
struct ide_cmd *cmd) { return 1; }
static inline void ide_dma_unmap_sg(ide_drive_t *drive,
struct ide_cmd *cmd) { ; }
#endif /* CONFIG_BLK_DEV_IDEDMA */
#ifdef CONFIG_BLK_DEV_IDEACPI
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册