From 83ae5957ececb9b47eb19a9e9e4170ef072c2759 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 27 Mar 2009 13:36:10 +0300 Subject: [PATCH] --- yaml --- r: 137691 b: refs/heads/master c: 5291658d87ac1ae60418e79e7b6bad7d5f595e0c h: refs/heads/master i: 137689: 0146d39f169b0de784f45b73d0bdab151c52c7d8 137687: 80f64d500a59215c893af009f73b5f2eb1a8871c v: v3 --- [refs] | 2 +- trunk/arch/m68k/include/asm/ide.h | 73 +++++ trunk/drivers/ide/alim15x3.c | 9 +- trunk/drivers/ide/at91_ide.c | 70 ++--- trunk/drivers/ide/au1xxx-ide.c | 39 ++- trunk/drivers/ide/buddha.c | 11 +- trunk/drivers/ide/cmd64x.c | 6 +- trunk/drivers/ide/cs5536.c | 2 +- trunk/drivers/ide/delkin_cb.c | 1 - trunk/drivers/ide/dtc2278.c | 3 +- trunk/drivers/ide/falconide.c | 45 +-- trunk/drivers/ide/gayle.c | 7 +- trunk/drivers/ide/hpt366.c | 6 +- trunk/drivers/ide/icside.c | 24 +- trunk/drivers/ide/ide-4drives.c | 3 +- trunk/drivers/ide/ide-acpi.c | 10 +- trunk/drivers/ide/ide-atapi.c | 123 ++++---- trunk/drivers/ide/ide-cd.c | 155 +++++------ trunk/drivers/ide/ide-cd.h | 4 +- trunk/drivers/ide/ide-cs.c | 1 - trunk/drivers/ide/ide-devsets.c | 4 +- trunk/drivers/ide/ide-disk.c | 171 ++++++------ trunk/drivers/ide/ide-disk_proc.c | 28 +- trunk/drivers/ide/ide-dma-sff.c | 37 ++- trunk/drivers/ide/ide-dma.c | 39 ++- trunk/drivers/ide/ide-eh.c | 30 +- trunk/drivers/ide/ide-floppy.c | 156 ++++++----- trunk/drivers/ide/ide-gd.c | 10 +- trunk/drivers/ide/ide-gd.h | 4 +- trunk/drivers/ide/ide-generic.c | 8 +- trunk/drivers/ide/ide-h8300.c | 66 ++--- trunk/drivers/ide/ide-io-std.c | 73 +++-- trunk/drivers/ide/ide-io.c | 285 ++++++++++++------- trunk/drivers/ide/ide-ioctls.c | 44 +-- trunk/drivers/ide/ide-iops.c | 66 +++-- trunk/drivers/ide/ide-lib.c | 20 +- trunk/drivers/ide/ide-park.c | 19 +- trunk/drivers/ide/ide-pm.c | 42 ++- trunk/drivers/ide/ide-pnp.c | 6 +- trunk/drivers/ide/ide-probe.c | 95 ++++--- trunk/drivers/ide/ide-proc.c | 16 +- trunk/drivers/ide/ide-tape.c | 123 +++++--- trunk/drivers/ide/ide-taskfile.c | 448 ++++++++++++++++-------------- trunk/drivers/ide/ide_arm.c | 6 +- trunk/drivers/ide/it821x.c | 2 +- trunk/drivers/ide/macide.c | 7 +- trunk/drivers/ide/ns87415.c | 36 +-- trunk/drivers/ide/palm_bk3710.c | 13 +- trunk/drivers/ide/pdc202xx_old.c | 4 +- trunk/drivers/ide/pmac.c | 32 ++- trunk/drivers/ide/q40ide.c | 15 +- trunk/drivers/ide/sc1200.c | 2 +- trunk/drivers/ide/scc_pata.c | 115 ++++---- trunk/drivers/ide/setup-pci.c | 4 - trunk/drivers/ide/sgiioc4.c | 30 +- trunk/drivers/ide/siimage.c | 2 +- trunk/drivers/ide/sl82c105.c | 2 +- trunk/drivers/ide/tc86c001.c | 2 +- trunk/drivers/ide/trm290.c | 15 +- trunk/drivers/ide/tx4938ide.c | 68 +++-- trunk/drivers/ide/tx4939ide.c | 109 ++++---- trunk/fs/fuse/file.c | 3 +- trunk/fs/jfs/Kconfig | 1 - trunk/fs/jfs/jfs_extent.c | 63 +++-- trunk/fs/jfs/jfs_imap.c | 10 +- trunk/fs/jfs/jfs_metapage.c | 18 +- trunk/fs/jfs/jfs_types.h | 29 ++ trunk/fs/jfs/jfs_xtree.c | 263 +++++++++++++++++- trunk/fs/jfs/jfs_xtree.h | 2 + trunk/fs/jfs/super.c | 4 - trunk/include/linux/ide.h | 239 ++++++++-------- 71 files changed, 2014 insertions(+), 1466 deletions(-) diff --git a/[refs] b/[refs] index 5d0850fdd3d6..9de68d675de5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 83826dc505e6c6f432332dd45681be4bb71635ce +refs/heads/master: 5291658d87ac1ae60418e79e7b6bad7d5f595e0c diff --git a/trunk/arch/m68k/include/asm/ide.h b/trunk/arch/m68k/include/asm/ide.h index 3958726664ba..b996a3c8cff5 100644 --- a/trunk/arch/m68k/include/asm/ide.h +++ b/trunk/arch/m68k/include/asm/ide.h @@ -30,28 +30,101 @@ #define _M68K_IDE_H #ifdef __KERNEL__ + + #include #include #include +#ifdef CONFIG_ATARI +#include +#include +#endif + +#ifdef CONFIG_MAC +#include +#endif + /* * Get rid of defs from io.h - ide has its private and conflicting versions * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we * always use the `raw' MMIO versions */ +#undef inb +#undef inw +#undef insw +#undef inl +#undef insl +#undef outb +#undef outw +#undef outsw +#undef outl +#undef outsl #undef readb #undef readw +#undef readl #undef writeb #undef writew +#undef writel +#define inb in_8 +#define inw in_be16 +#define insw(port, addr, n) raw_insw((u16 *)port, addr, n) +#define inl in_be32 +#define insl(port, addr, n) raw_insl((u32 *)port, addr, n) +#define outb(val, port) out_8(port, val) +#define outw(val, port) out_be16(port, val) +#define outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) +#define outl(val, port) out_be32(port, val) +#define outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) #define readb in_8 #define readw in_be16 #define __ide_mm_insw(port, addr, n) raw_insw((u16 *)port, addr, n) +#define readl in_be32 #define __ide_mm_insl(port, addr, n) raw_insl((u32 *)port, addr, n) #define writeb(val, port) out_8(port, val) #define writew(val, port) out_be16(port, val) #define __ide_mm_outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) +#define writel(val, port) out_be32(port, val) #define __ide_mm_outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) +#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) +#define insw_swapw(port, addr, n) raw_insw_swapw((u16 *)port, addr, n) +#define outsw_swapw(port, addr, n) raw_outsw_swapw((u16 *)port, addr, n) +#endif + +#ifdef CONFIG_BLK_DEV_FALCON_IDE +#define IDE_ARCH_LOCK + +extern int falconide_intr_lock; + +static __inline__ void ide_release_lock (void) +{ + if (MACH_IS_ATARI) { + if (falconide_intr_lock == 0) { + printk("ide_release_lock: bug\n"); + return; + } + falconide_intr_lock = 0; + stdma_release(); + } +} + +static __inline__ void +ide_get_lock(irq_handler_t handler, void *data) +{ + if (MACH_IS_ATARI) { + if (falconide_intr_lock == 0) { + if (in_interrupt() > 0) + panic( "Falcon IDE hasn't ST-DMA lock in interrupt" ); + stdma_lock(handler, data); + falconide_intr_lock = 1; + } + } +} +#endif /* CONFIG_BLK_DEV_FALCON_IDE */ + +#define IDE_ARCH_ACK_INTR +#define ide_ack_intr(hwif) ((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1) #endif /* __KERNEL__ */ #endif /* _M68K_IDE_H */ diff --git a/trunk/drivers/ide/alim15x3.c b/trunk/drivers/ide/alim15x3.c index d516168464fc..d3513b6b8530 100644 --- a/trunk/drivers/ide/alim15x3.c +++ b/trunk/drivers/ide/alim15x3.c @@ -191,18 +191,17 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) /** * ali15x3_dma_setup - begin a DMA phase * @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 ali15x3_dma_setup(ide_drive_t *drive) { if (m5229_revision < 0xC2 && drive->media != ide_disk) { - if (cmd->tf_flags & IDE_TFLAG_WRITE) + if (rq_data_dir(drive->hwif->rq)) return 1; /* try PIO instead of DMA */ } - return ide_dma_setup(drive, cmd); + return ide_dma_setup(drive); } /** @@ -504,11 +503,11 @@ 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_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/at91_ide.c b/trunk/drivers/ide/at91_ide.c index 27547121daff..1bb50f46388d 100644 --- a/trunk/drivers/ide/at91_ide.c +++ b/trunk/drivers/ide/at91_ide.c @@ -143,7 +143,7 @@ static void apply_timings(const u8 chipselect, const u8 pio, set_smc_timings(chipselect, cycle, setup, pulse, data_float, use_iordy); } -static void at91_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void at91_ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; @@ -156,11 +156,11 @@ static void at91_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, len++; enter_16bit(chipselect, mode); - readsw((void __iomem *)io_ports->data_addr, buf, len / 2); + __ide_mm_insw((void __iomem *) io_ports->data_addr, buf, len / 2); leave_16bit(chipselect, mode); } -static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void at91_ide_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; @@ -171,7 +171,7 @@ static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, pdbg("cs %u buf %p len %d\n", chipselect, buf, len); enter_16bit(chipselect, mode); - writesw((void __iomem *)io_ports->data_addr, buf, len / 2); + __ide_mm_outsw((void __iomem *) io_ports->data_addr, buf, len / 2); leave_16bit(chipselect, mode); } @@ -185,55 +185,55 @@ static void ide_mm_outb(u8 value, unsigned long port) writeb(value, (void __iomem *) port); } -static void at91_ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void at91_ide_tf_load(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; - u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; - if (cmd->tf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->tf_flags & IDE_FTFLAG_OUT_DATA) { + if (task->tf_flags & IDE_TFLAG_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) + if (task->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) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) ide_mm_outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) ide_mm_outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) ide_mm_outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) ide_mm_outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) ide_mm_outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) ide_mm_outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) ide_mm_outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) ide_mm_outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) ide_mm_outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) ide_mm_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } -static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void at91_ide_tf_read(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; - if (cmd->tf_flags & IDE_FTFLAG_IN_DATA) { + if (task->tf_flags & IDE_TFLAG_IN_DATA) { u16 data; at91_ide_input_data(drive, NULL, &data, 2); @@ -244,31 +244,31 @@ static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) /* be sure we're looking at the low order bits */ ide_mm_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) tf->feature = ide_mm_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = ide_mm_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = ide_mm_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = ide_mm_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = ide_mm_inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = ide_mm_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { + if (task->tf_flags & IDE_TFLAG_LBA48) { ide_mm_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + if (task->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_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr); } } diff --git a/trunk/drivers/ide/au1xxx-ide.c b/trunk/drivers/ide/au1xxx-ide.c index d3a9d6c15328..154ec2cf734f 100644 --- a/trunk/drivers/ide/au1xxx-ide.c +++ b/trunk/drivers/ide/au1xxx-ide.c @@ -86,13 +86,13 @@ void auide_outsw(unsigned long port, void *addr, u32 count) ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp); } -static void au1xxx_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void au1xxx_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { auide_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); } -static void au1xxx_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void au1xxx_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { auide_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); @@ -209,17 +209,23 @@ static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed) */ #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA -static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) +static int auide_build_dmatable(ide_drive_t *drive) { + int i, iswrite, count = 0; ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->rq; _auide_hwif *ahwif = &auide_hwif; struct scatterlist *sg; - int i = cmd->sg_nents, count = 0; - int iswrite = !!(cmd->tf_flags & IDE_TFLAG_WRITE); + iswrite = (rq_data_dir(rq) == WRITE); /* Save for interrupt context */ ahwif->drive = drive; + hwif->sg_nents = i = ide_build_sglist(drive, rq); + + if (!i) + return 0; + /* fill the descriptors */ sg = hwif->sg_table; while (i && sg_dma_len(sg)) { @@ -280,7 +286,12 @@ static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) static int auide_dma_end(ide_drive_t *drive) { - ide_destroy_dmatable(drive); + ide_hwif_t *hwif = drive->hwif; + + if (hwif->sg_nents) { + ide_destroy_dmatable(drive); + hwif->sg_nents = 0; + } return 0; } @@ -290,10 +301,19 @@ static void auide_dma_start(ide_drive_t *drive ) } -static int auide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command) { - if (auide_build_dmatable(drive, cmd) == 0) { - ide_map_sg(drive, cmd); + /* issue cmd to drive */ + ide_execute_command(drive, command, &ide_dma_intr, + (2*WAIT_CMD), NULL); +} + +static int auide_dma_setup(ide_drive_t *drive) +{ + struct request *rq = drive->hwif->rq; + + if (!auide_build_dmatable(drive)) { + ide_map_sg(drive, rq); return 1; } @@ -349,6 +369,7 @@ static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 de static const struct ide_dma_ops au1xxx_dma_ops = { .dma_host_set = auide_dma_host_set, .dma_setup = auide_dma_setup, + .dma_exec_cmd = auide_dma_exec_cmd, .dma_start = auide_dma_start, .dma_end = auide_dma_end, .dma_test_irq = auide_dma_test_irq, diff --git a/trunk/drivers/ide/buddha.c b/trunk/drivers/ide/buddha.c index d028f8864bc1..c5a3c9ef6a5d 100644 --- a/trunk/drivers/ide/buddha.c +++ b/trunk/drivers/ide/buddha.c @@ -143,11 +143,6 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base, hw->chipset = ide_generic; } -static const struct ide_port_info buddha_port_info = { - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, -}; - /* * Probe for a Buddha or Catweasel IDE interface */ @@ -177,6 +172,10 @@ static int __init buddha_init(void) board = z->resource.start; +/* + * FIXME: we now have selectable mmio v/s iomio transports. + */ + if(type != BOARD_XSURF) { if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE")) continue; @@ -225,7 +224,7 @@ static int __init buddha_init(void) hws[i] = &hw[i]; } - ide_host_add(&buddha_port_info, hws, NULL); + ide_host_add(NULL, hws, NULL); } return 0; diff --git a/trunk/drivers/ide/cmd64x.c b/trunk/drivers/ide/cmd64x.c index bf0e3f470824..aeee036b1503 100644 --- a/trunk/drivers/ide/cmd64x.c +++ b/trunk/drivers/ide/cmd64x.c @@ -379,11 +379,11 @@ static const struct ide_port_ops cmd64x_port_ops = { static const struct ide_dma_ops cmd64x_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = cmd64x_dma_end, .dma_test_irq = cmd64x_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; @@ -391,11 +391,11 @@ static const struct ide_dma_ops cmd64x_dma_ops = { static const struct ide_dma_ops cmd646_rev1_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = cmd646_1_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; @@ -403,11 +403,11 @@ static const struct ide_dma_ops cmd646_rev1_dma_ops = { static const struct ide_dma_ops cmd648_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = cmd648_dma_end, .dma_test_irq = cmd648_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/cs5536.c b/trunk/drivers/ide/cs5536.c index d5dcf4899607..7a62db719a46 100644 --- a/trunk/drivers/ide/cs5536.c +++ b/trunk/drivers/ide/cs5536.c @@ -231,11 +231,11 @@ static const struct ide_port_ops cs5536_port_ops = { static const struct ide_dma_ops cs5536_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = cs5536_dma_start, .dma_end = cs5536_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, }; diff --git a/trunk/drivers/ide/delkin_cb.c b/trunk/drivers/ide/delkin_cb.c index f153b95619bb..bacb1194c9c9 100644 --- a/trunk/drivers/ide/delkin_cb.c +++ b/trunk/drivers/ide/delkin_cb.c @@ -66,7 +66,6 @@ static const struct ide_port_info delkin_cb_port_info = { .port_ops = &delkin_cb_port_ops, .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS | IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, .init_chipset = delkin_cb_init_chipset, }; diff --git a/trunk/drivers/ide/dtc2278.c b/trunk/drivers/ide/dtc2278.c index c6b138122981..689b2e493413 100644 --- a/trunk/drivers/ide/dtc2278.c +++ b/trunk/drivers/ide/dtc2278.c @@ -100,8 +100,7 @@ static const struct ide_port_info dtc2278_port_info __initdata = { IDE_HFLAG_IO_32BIT | /* disallow ->io_32bit changes */ IDE_HFLAG_NO_IO_32BIT | - IDE_HFLAG_NO_DMA | - IDE_HFLAG_DTC2278, + IDE_HFLAG_NO_DMA, .pio_mask = ATA_PIO4, }; diff --git a/trunk/drivers/ide/falconide.c b/trunk/drivers/ide/falconide.c index b368a5effc3a..a638e952d67a 100644 --- a/trunk/drivers/ide/falconide.c +++ b/trunk/drivers/ide/falconide.c @@ -40,48 +40,29 @@ * which is shared between several drivers. */ -static int falconide_intr_lock; +int falconide_intr_lock; +EXPORT_SYMBOL(falconide_intr_lock); -static void falconide_release_lock(void) -{ - if (falconide_intr_lock == 0) { - printk(KERN_ERR "%s: bug\n", __func__); - return; - } - falconide_intr_lock = 0; - stdma_release(); -} - -static void falconide_get_lock(irq_handler_t handler, void *data) -{ - if (falconide_intr_lock == 0) { - if (in_interrupt() > 0) - panic("Falcon IDE hasn't ST-DMA lock in interrupt"); - stdma_lock(handler, data); - falconide_intr_lock = 1; - } -} - -static void falconide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void falconide_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; - if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) + if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) return insw(data_addr, buf, (len + 1) / 2); - raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2); + insw_swapw(data_addr, buf, (len + 1) / 2); } -static void falconide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void falconide_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; - if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) + if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) return outsw(data_addr, buf, (len + 1) / 2); - raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2); + outsw_swapw(data_addr, buf, (len + 1) / 2); } /* Atari has a byte-swapped IDE interface */ @@ -100,12 +81,8 @@ static const struct ide_tp_ops falconide_tp_ops = { }; static const struct ide_port_info falconide_port_info = { - .get_lock = falconide_get_lock, - .release_lock = falconide_release_lock, .tp_ops = &falconide_tp_ops, - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE | - IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, + .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_SERIALIZE, }; static void __init falconide_setup_ports(hw_regs_t *hw) @@ -155,9 +132,9 @@ static int __init falconide_init(void) goto err; } - falconide_get_lock(NULL, NULL); + ide_get_lock(NULL, NULL); rc = ide_host_register(host, &falconide_port_info, hws); - falconide_release_lock(); + ide_release_lock(); if (rc) goto err_free; diff --git a/trunk/drivers/ide/gayle.c b/trunk/drivers/ide/gayle.c index dc778251cb05..59bd0be9dcb3 100644 --- a/trunk/drivers/ide/gayle.c +++ b/trunk/drivers/ide/gayle.c @@ -118,9 +118,7 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base, } static const struct ide_port_info gayle_port_info = { - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE | - IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, + .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA, }; /* @@ -165,6 +163,9 @@ static int __init gayle_init(void) irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200); ack_intr = gayle_ack_intr_a1200; } +/* + * FIXME: we now have selectable modes between mmio v/s iomio + */ res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1); res_n = GAYLE_IDEREG_SIZE; diff --git a/trunk/drivers/ide/hpt366.c b/trunk/drivers/ide/hpt366.c index dbaf184ed9c5..d3b3e824f445 100644 --- a/trunk/drivers/ide/hpt366.c +++ b/trunk/drivers/ide/hpt366.c @@ -1418,11 +1418,11 @@ static const struct ide_port_ops hpt3xx_port_ops = { static const struct ide_dma_ops hpt37x_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = hpt374_dma_end, .dma_test_irq = hpt374_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; @@ -1430,11 +1430,11 @@ static const struct ide_dma_ops hpt37x_dma_ops = { static const struct ide_dma_ops hpt370_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = hpt370_dma_start, .dma_end = hpt370_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = hpt370_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; @@ -1442,11 +1442,11 @@ static const struct ide_dma_ops hpt370_dma_ops = { static const struct ide_dma_ops hpt36x_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = hpt366_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/icside.c b/trunk/drivers/ide/icside.c index 51ce404fe532..415d7e24f2b6 100644 --- a/trunk/drivers/ide/icside.c +++ b/trunk/drivers/ide/icside.c @@ -307,14 +307,15 @@ static void icside_dma_start(ide_drive_t *drive) enable_dma(ec->dma); } -static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static int icside_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct expansion_card *ec = ECARD_DEV(hwif->dev); struct icside_state *state = ecard_get_drvdata(ec); + struct request *rq = hwif->rq; unsigned int dma_mode; - if (cmd->tf_flags & IDE_TFLAG_WRITE) + if (rq_data_dir(rq)) dma_mode = DMA_MODE_WRITE; else dma_mode = DMA_MODE_READ; @@ -324,6 +325,8 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) */ BUG_ON(dma_channel_active(ec->dma)); + hwif->sg_nents = ide_build_sglist(drive, rq); + /* * Ensure that we have the right interrupt routed. */ @@ -343,7 +346,7 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) * Tell the DMA engine about the SG table and * data direction. */ - set_dma_sg(ec->dma, hwif->sg_table, cmd->sg_nents); + set_dma_sg(ec->dma, hwif->sg_table, hwif->sg_nents); set_dma_mode(ec->dma, dma_mode); drive->waiting_for_dma = 1; @@ -351,6 +354,12 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) return 0; } +static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd) +{ + /* issue cmd to drive */ + ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD, NULL); +} + static int icside_dma_test_irq(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; @@ -374,6 +383,7 @@ static int icside_dma_init(ide_hwif_t *hwif, const struct ide_port_info *d) static const struct ide_dma_ops icside_v6_dma_ops = { .dma_host_set = icside_dma_host_set, .dma_setup = icside_dma_setup, + .dma_exec_cmd = icside_dma_exec_cmd, .dma_start = icside_dma_start, .dma_end = icside_dma_end, .dma_test_irq = icside_dma_test_irq, @@ -409,10 +419,6 @@ static void icside_setup_ports(hw_regs_t *hw, void __iomem *base, hw->chipset = ide_acorn; } -static const struct ide_port_info icside_v5_port_info = { - .host_flags = IDE_HFLAG_NO_DMA, -}; - static int __devinit icside_register_v5(struct icside_state *state, struct expansion_card *ec) { @@ -439,7 +445,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec); - host = ide_host_alloc(&icside_v5_port_info, hws); + host = ide_host_alloc(NULL, hws); if (host == NULL) return -ENODEV; @@ -447,7 +453,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) ecard_set_drvdata(ec, state); - ret = ide_host_register(host, &icside_v5_port_info, hws); + ret = ide_host_register(host, NULL, hws); if (ret) goto err_free; diff --git a/trunk/drivers/ide/ide-4drives.c b/trunk/drivers/ide/ide-4drives.c index 78aca75a2c48..9e85b1ec9607 100644 --- a/trunk/drivers/ide/ide-4drives.c +++ b/trunk/drivers/ide/ide-4drives.c @@ -23,8 +23,7 @@ static const struct ide_port_ops ide_4drives_port_ops = { static const struct ide_port_info ide_4drives_port_info = { .port_ops = &ide_4drives_port_ops, - .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA | - IDE_HFLAG_4DRIVES, + .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA, }; static int __init ide_4drives_init(void) diff --git a/trunk/drivers/ide/ide-acpi.c b/trunk/drivers/ide/ide-acpi.c index 12f436951bff..5b704f1ea90c 100644 --- a/trunk/drivers/ide/ide-acpi.c +++ b/trunk/drivers/ide/ide-acpi.c @@ -304,7 +304,7 @@ static int do_drive_set_taskfiles(ide_drive_t *drive, /* send all taskfile registers (0x1f1-0x1f7) *in*that*order* */ for (ix = 0; ix < gtf_count; ix++) { u8 *gtf = (u8 *)(gtf_address + ix * REGS_PER_GTF); - struct ide_cmd cmd; + ide_task_t task; DEBPRINT("(0x1f1-1f7): " "hex: %02x %02x %02x %02x %02x %02x %02x\n", @@ -317,11 +317,11 @@ static int do_drive_set_taskfiles(ide_drive_t *drive, } /* convert GTF to taskfile */ - memset(&cmd, 0, sizeof(cmd)); - memcpy(&cmd.tf_array[7], gtf, REGS_PER_GTF); - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + memset(&task, 0, sizeof(ide_task_t)); + memcpy(&task.tf_array[7], gtf, REGS_PER_GTF); + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - err = ide_no_data_taskfile(drive, &cmd); + err = ide_no_data_taskfile(drive, &task); if (err) { printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n", __func__, err); diff --git a/trunk/drivers/ide/ide-atapi.c b/trunk/drivers/ide/ide-atapi.c index 2fb5d28a9be5..6adc5b4a4406 100644 --- a/trunk/drivers/ide/ide-atapi.c +++ b/trunk/drivers/ide/ide-atapi.c @@ -302,16 +302,16 @@ EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | - IDE_TFLAG_IN_NSECT; + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | + IDE_TFLAG_IN_NSECT; - drive->hwif->tp_ops->tf_read(drive, &cmd); + drive->hwif->tp_ops->tf_read(drive, &task); - *bcount = (cmd.tf.lbah << 8) | cmd.tf.lbam; - *ireason = cmd.tf.nsect & 3; + *bcount = (task.tf.lbah << 8) | task.tf.lbam; + *ireason = task.tf.nsect & 3; } EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); @@ -336,6 +336,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD : WAIT_TAPE_CMD; + if (pc->flags & PC_FLAG_TIMEDOUT) { + drive->pc_callback(drive, 0); + return ide_stopped; + } + /* Clear the interrupt */ stat = tp_ops->read_status(hwif); @@ -357,8 +362,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) /* No more interrupts */ if ((stat & ATA_DRQ) == 0) { - int uptodate; - debug_log("Packet command completed, %d bytes transferred\n", pc->xferred); @@ -397,22 +400,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) dsc = 1; /* Command finished - Call the callback function */ - uptodate = drive->pc_callback(drive, dsc); - - if (uptodate == 0) - drive->failed_pc = NULL; - - if (blk_special_request(rq)) { - rq->errors = 0; - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); - } 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)); - } + drive->pc_callback(drive, dsc); return ide_stopped; } @@ -470,8 +458,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) /* FIXME: don't do partial completions */ if (drive->media == ide_floppy) - ide_complete_rq(drive, 0, - done ? done : ide_rq_bytes(rq)); + ide_end_request(drive, 1, done >> 9); } else xferfunc(drive, NULL, pc->cur_pos, bcount); @@ -483,32 +470,39 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) rq->cmd[0], bcount); next_irq: /* And set the interrupt handler again */ - ide_set_handler(drive, ide_pc_intr, timeout); + ide_set_handler(drive, ide_pc_intr, timeout, NULL); return ide_started; } -static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags, - u16 bcount, u8 dma) +static void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount) { - cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO; - cmd->tf_flags |= IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | - IDE_TFLAG_OUT_FEATURE | tf_flags; - cmd->tf.command = ATA_CMD_PACKET; - cmd->tf.feature = dma; /* Use PIO/DMA */ - cmd->tf.lbam = bcount & 0xff; - cmd->tf.lbah = (bcount >> 8) & 0xff; + ide_hwif_t *hwif = drive->hwif; + ide_task_t task; + u8 dma = drive->dma; + + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | + IDE_TFLAG_OUT_FEATURE | tf_flags; + task.tf.feature = dma; /* Use PIO/DMA */ + task.tf.lbam = bcount & 0xff; + task.tf.lbah = (bcount >> 8) & 0xff; + + ide_tf_dump(drive->name, &task.tf); + hwif->tp_ops->set_irq(hwif, 1); + SELECT_MASK(drive, 0); + hwif->tp_ops->tf_load(drive, &task); } static u8 ide_read_ireason(ide_drive_t *drive) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_IN_NSECT; + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_IN_NSECT; - drive->hwif->tp_ops->tf_read(drive, &cmd); + drive->hwif->tp_ops->tf_read(drive, &task); - return cmd.tf.nsect & 3; + return task.tf.nsect & 3; } static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) @@ -603,13 +597,11 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) } } - hwif->expiry = expiry; - /* Set the interrupt routine */ ide_set_handler(drive, (dev_is_idecd(drive) ? drive->irq_handler : ide_pc_intr), - timeout); + timeout, expiry); /* Begin DMA, if necessary */ if (dev_is_idecd(drive)) { @@ -629,30 +621,23 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) return ide_started; } -ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) +ide_startstop_t ide_issue_pc(ide_drive_t *drive) { 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; u32 tf_flags; u16 bcount; - u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT); if (dev_is_idecd(drive)) { tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; - bcount = ide_cd_get_xferlen(rq); + bcount = ide_cd_get_xferlen(hwif->rq); 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 = !hwif->dma_ops->dma_setup(drive); } else { pc = drive->pc; @@ -671,12 +656,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) } 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; - } + (drive->dev_flags & IDE_DFLAG_USING_DMA)) + drive->dma = !hwif->dma_ops->dma_setup(drive); if (!drive->dma) pc->flags &= ~PC_FLAG_DMA_OK; @@ -685,18 +666,18 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) : WAIT_TAPE_CMD; } - ide_init_packet_cmd(cmd, tf_flags, bcount, drive->dma); + ide_pktcmd_tf_load(drive, tf_flags, bcount); - (void)do_rw_taskfile(drive, cmd); - - if (drq_int) { + /* Issue the packet command */ + if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { if (drive->dma) drive->waiting_for_dma = 0; - hwif->expiry = expiry; + ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, + timeout, expiry); + return ide_started; + } else { + ide_execute_pkt_cmd(drive); + return ide_transfer_pc(drive); } - - ide_execute_command(drive, cmd, ide_transfer_pc, timeout); - - return drq_int ? ide_started : ide_transfer_pc(drive); } EXPORT_SYMBOL_GPL(ide_issue_pc); diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c index 3f630e4080d4..2177cd11664c 100644 --- a/trunk/drivers/ide/ide-cd.c +++ b/trunk/drivers/ide/ide-cd.c @@ -100,7 +100,8 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, { int log = 0; - ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key); + ide_debug_log(IDE_DBG_SENSE, "Call %s, sense_key: 0x%x\n", __func__, + sense->sense_key); if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) return 0; @@ -150,12 +151,13 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, unsigned long bio_sectors; struct cdrom_info *info = drive->driver_data; - ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x", - sense->error_code, sense->sense_key); + ide_debug_log(IDE_DBG_SENSE, "Call %s, error_code: 0x%x, " + "sense_key: 0x%x\n", __func__, sense->error_code, + sense->sense_key); if (failed_command) - ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x", - failed_command->cmd[0]); + ide_debug_log(IDE_DBG_SENSE, "%s: failed cmd: 0x%x\n", + __func__, failed_command->cmd[0]); if (!cdrom_log_sense(drive, failed_command, sense)) return; @@ -213,9 +215,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, struct request *failed_command) { struct cdrom_info *info = drive->driver_data; - struct request *rq = &drive->request_sense_rq; + struct request *rq = &info->request_sense_request; - ide_debug_log(IDE_DBG_SENSE, "enter"); + ide_debug_log(IDE_DBG_SENSE, "Call %s\n", __func__); if (sense == NULL) sense = &info->sense_data; @@ -237,8 +239,8 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, rq->buffer = (void *) failed_command; if (failed_command) - ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x", - failed_command->cmd[0]); + ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n", + failed_command->cmd[0]); drive->hwif->rq = NULL; @@ -250,8 +252,9 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) struct request *rq = drive->hwif->rq; int nsectors = rq->hard_cur_sectors; - ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, uptodate: 0x%x, nsectors: %d", - rq->cmd[0], uptodate, nsectors); + ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, " + "nsectors: %d\n", __func__, rq->cmd[0], uptodate, + nsectors); if (blk_sense_request(rq) && uptodate) { /* @@ -272,8 +275,8 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) * now end the failed request */ if (blk_fs_request(failed)) { - if (ide_end_rq(drive, failed, -EIO, - failed->hard_nr_sectors << 9)) + if (ide_end_dequeued_request(drive, failed, 0, + failed->hard_nr_sectors)) BUG(); } else { if (blk_end_request(failed, -EIO, @@ -292,13 +295,10 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) if (!nsectors) nsectors = 1; - ide_debug_log(IDE_DBG_FUNC, "uptodate: 0x%x, nsectors: %d", - uptodate, nsectors); + ide_debug_log(IDE_DBG_FUNC, "Exit %s, uptodate: 0x%x, nsectors: %d\n", + __func__, uptodate, nsectors); - if (blk_fs_request(rq) == 0 && uptodate <= 0 && rq->errors == 0) - rq->errors = -EIO; - - ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); + ide_end_request(drive, uptodate, nsectors); } static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st) @@ -338,10 +338,9 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) return 1; } - ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, " - "rq->cmd_type: 0x%x, err: 0x%x", - stat, good_stat, rq->cmd[0], rq->cmd_type, - err); + ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, " + "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n", + __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err); if (blk_sense_request(rq)) { /* @@ -531,7 +530,8 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, { ide_hwif_t *hwif = drive->hwif; - ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw); + ide_debug_log(IDE_DBG_FUNC, "Call %s, ireason: 0x%x, rw: 0x%x\n", + __func__, ireason, rw); /* * ireason == 0: the drive wants to receive data from us @@ -572,7 +572,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, */ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) { - ide_debug_log(IDE_DBG_FUNC, "len: %d", len); + ide_debug_log(IDE_DBG_FUNC, "Call %s, len: %d\n", __func__, len); if ((len % SECTOR_SIZE) == 0) return 0; @@ -594,7 +594,8 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, struct request *rq) { - ide_debug_log(IDE_DBG_RQ, "rq->cmd_flags: 0x%x", rq->cmd_flags); + ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd_flags: 0x%x\n", __func__, + rq->cmd_flags); if (rq_data_dir(rq) == READ) { unsigned short sectors_per_frame = @@ -638,7 +639,7 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) { - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); if (rq->buffer != bio_data(rq->bio)) { sector_t n = @@ -657,7 +658,8 @@ static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) { - ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]); + ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n", + __func__, rq->cmd[0]); /* * Some of the trailing request sense fields are optional, @@ -684,9 +686,9 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, if (!sense) sense = &local_sense; - ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, " - "cmd_flags: 0x%x", - cmd[0], write, timeout, cmd_flags); + ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, " + "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write, + timeout, cmd_flags); /* start of retry loop */ do { @@ -770,8 +772,8 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) u16 len; u8 ireason; - ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x", - rq->cmd[0], write); + ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x\n", + __func__, rq->cmd[0], write); /* check for errors */ dma = drive->dma; @@ -793,11 +795,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (dma_error) return ide_error(drive, "dma error", stat); if (blk_fs_request(rq)) { - ide_complete_rq(drive, 0, rq->nr_sectors - ? (rq->nr_sectors << 9) : ide_rq_bytes(rq)); + ide_end_request(drive, 1, rq->nr_sectors); return ide_stopped; } else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) { - ide_complete_rq(drive, 0, 512); + ide_end_request(drive, 1, 1); return ide_stopped; } goto end_request; @@ -809,8 +810,8 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (thislen > len) thislen = len; - ide_debug_log(IDE_DBG_PC, "DRQ: stat: 0x%x, thislen: %d", - stat, thislen); + ide_debug_log(IDE_DBG_PC, "%s: DRQ: stat: 0x%x, thislen: %d\n", + __func__, stat, thislen); /* If DRQ is clear, the command has completed. */ if ((stat & ATA_DRQ) == 0) { @@ -875,9 +876,8 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) xferfunc = hwif->tp_ops->input_data; } - ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, " - "ireason: 0x%x", - rq->cmd_type, ireason); + ide_debug_log(IDE_DBG_PC, "%s: data transfer, rq->cmd_type: 0x%x, " + "ireason: 0x%x\n", __func__, rq->cmd_type, ireason); /* transfer data */ while (thislen > 0) { @@ -959,8 +959,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) expiry = ide_cd_expiry; } - hwif->expiry = expiry; - ide_set_handler(drive, cdrom_newpc_intr, timeout); + ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry); return ide_started; end_request: @@ -989,9 +988,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; - ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, write: 0x%x, " - "secs_per_frame: %u", - rq->cmd[0], write, sectors_per_frame); + ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, " + "secs_per_frame: %u\n", + __func__, rq->cmd[0], write, sectors_per_frame); if (write) { /* disk has become write protected */ @@ -1027,8 +1026,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) { - ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x", - rq->cmd[0], rq->cmd_type); + ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, " + "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0], + rq->cmd_type); if (blk_pc_request(rq)) rq->cmd_flags |= REQ_QUIET; @@ -1067,13 +1067,10 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, sector_t block) { - struct ide_cmd cmd; - - ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu", - rq->cmd[0], (unsigned long long)block); - - if (drive->debug_mask & IDE_DBG_RQ) - blk_dump_rq_flags(rq, "ide_cd_do_request"); + ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, " + "rq->cmd_type: 0x%x, block: %llu\n", + __func__, rq->cmd[0], rq->cmd_type, + (unsigned long long)block); if (blk_fs_request(rq)) { if (cdrom_start_rw(drive, rq) == ide_stopped) @@ -1097,14 +1094,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, return ide_stopped; } - memset(&cmd, 0, sizeof(cmd)); - - if (rq_data_dir(rq)) - cmd.tf_flags |= IDE_TFLAG_WRITE; - - cmd.rq = rq; - - return ide_issue_pc(drive, &cmd); + return ide_issue_pc(drive); } /* @@ -1129,7 +1119,7 @@ int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) struct cdrom_device_info *cdi = &info->devinfo; unsigned char cmd[BLK_MAX_CDB]; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_TEST_UNIT_READY; @@ -1157,7 +1147,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, unsigned len = sizeof(capbuf); u32 blocklen; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_READ_CDVD_CAPACITY; @@ -1189,8 +1179,8 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, *capacity = 1 + be32_to_cpu(capbuf.lba); *sectors_per_frame = blocklen >> SECTOR_BITS; - ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu", - *capacity, *sectors_per_frame); + ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n", + __func__, *capacity, *sectors_per_frame); return 0; } @@ -1201,7 +1191,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, { unsigned char cmd[BLK_MAX_CDB]; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); memset(cmd, 0, BLK_MAX_CDB); @@ -1231,7 +1221,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) long last_written; unsigned long sectors_per_frame = SECTORS_PER_FRAME; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); if (toc == NULL) { /* try to allocate space */ @@ -1393,7 +1383,7 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf) struct packet_command cgc; int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0) size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; @@ -1413,7 +1403,7 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) struct cdrom_info *cd = drive->driver_data; u16 curspeed, maxspeed; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) { curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]); @@ -1423,8 +1413,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]); } - ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u", - curspeed, maxspeed); + ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n", + __func__, curspeed, maxspeed); cd->current_speed = (curspeed + (176/2)) / 176; cd->max_speed = (maxspeed + (176/2)) / 176; @@ -1458,7 +1448,7 @@ static int ide_cdrom_register(ide_drive_t *drive, int nslots) struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *devinfo = &info->devinfo; - ide_debug_log(IDE_DBG_PROBE, "nslots: %d", nslots); + ide_debug_log(IDE_DBG_PROBE, "Call %s, nslots: %d\n", __func__, nslots); devinfo->ops = &ide_cdrom_dops; devinfo->speed = info->current_speed; @@ -1481,8 +1471,9 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) mechtype_t mechtype; int nslots = 1; - ide_debug_log(IDE_DBG_PROBE, "media: 0x%x, atapi_flags: 0x%lx", - drive->media, drive->atapi_flags); + ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->media: 0x%x, " + "drive->atapi_flags: 0x%lx\n", __func__, drive->media, + drive->atapi_flags); cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO | @@ -1763,7 +1754,7 @@ static int ide_cdrom_setup(ide_drive_t *drive) char *fw_rev = (char *)&id[ATA_ID_FW_REV]; int nslots; - ide_debug_log(IDE_DBG_PROBE, "enter"); + ide_debug_log(IDE_DBG_PROBE, "Call %s\n", __func__); blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn); blk_queue_dma_alignment(drive->queue, 31); @@ -1806,7 +1797,7 @@ static void ide_cd_remove(ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); ide_proc_unregister_driver(drive, info->driver); device_del(&info->dev); @@ -1824,7 +1815,7 @@ static void ide_cd_release(struct device *dev) ide_drive_t *drive = info->drive; struct gendisk *g = info->disk; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); kfree(info->toc); if (devinfo->handle == drive) @@ -1848,6 +1839,7 @@ static struct ide_driver ide_cdrom_driver = { .remove = ide_cd_remove, .version = IDECD_VERSION, .do_request = ide_cd_do_request, + .end_request = ide_end_request, #ifdef CONFIG_IDE_PROC_FS .proc_entries = ide_cd_proc_entries, .proc_devsets = ide_cd_proc_devsets, @@ -1982,8 +1974,9 @@ static int ide_cd_probe(ide_drive_t *drive) struct gendisk *g; struct request_sense sense; - ide_debug_log(IDE_DBG_PROBE, "driver_req: %s, media: 0x%x", - drive->driver_req, drive->media); + ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->driver_req: %s, " + "drive->media: 0x%x\n", __func__, drive->driver_req, + drive->media); if (!strstr("ide-cdrom", drive->driver_req)) goto failed; diff --git a/trunk/drivers/ide/ide-cd.h b/trunk/drivers/ide/ide-cd.h index 1d97101099ce..c878bfcf1116 100644 --- a/trunk/drivers/ide/ide-cd.h +++ b/trunk/drivers/ide/ide-cd.h @@ -11,7 +11,7 @@ #define IDECD_DEBUG_LOG 0 #if IDECD_DEBUG_LOG -#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args) +#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) #else #define ide_debug_log(lvl, fmt, args...) do {} while (0) #endif @@ -91,6 +91,8 @@ struct cdrom_info { on this device. */ struct request_sense sense_data; + struct request request_sense_request; + u8 max_speed; /* Max speed of the drive. */ u8 current_speed; /* Current speed of the drive. */ diff --git a/trunk/drivers/ide/ide-cs.c b/trunk/drivers/ide/ide-cs.c index 9e47f3529d55..f50210fe558f 100644 --- a/trunk/drivers/ide/ide-cs.c +++ b/trunk/drivers/ide/ide-cs.c @@ -154,7 +154,6 @@ static const struct ide_port_ops idecs_port_ops = { static const struct ide_port_info idecs_port_info = { .port_ops = &idecs_port_ops, .host_flags = IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, }; static struct ide_host *idecs_register(unsigned long io, unsigned long ctl, diff --git a/trunk/drivers/ide/ide-devsets.c b/trunk/drivers/ide/ide-devsets.c index 5bf958e5b1d5..7c3953414d47 100644 --- a/trunk/drivers/ide/ide-devsets.c +++ b/trunk/drivers/ide/ide-devsets.c @@ -183,6 +183,8 @@ ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq) err = setfunc(drive, *(int *)&rq->cmd[1]); if (err) rq->errors = err; - ide_complete_rq(drive, err, ide_rq_bytes(rq)); + else + err = 1; + ide_end_request(drive, err, 0); return ide_stopped; } diff --git a/trunk/drivers/ide/ide-disk.c b/trunk/drivers/ide/ide-disk.c index ca934c8a1289..806760d24cef 100644 --- a/trunk/drivers/ide/ide-disk.c +++ b/trunk/drivers/ide/ide-disk.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -52,26 +53,33 @@ static const u8 ide_rw_cmds[] = { ATA_CMD_WRITE_EXT, }; -static void ide_tf_set_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 dma) +static const u8 ide_data_phases[] = { + TASKFILE_MULTI_IN, + TASKFILE_MULTI_OUT, + TASKFILE_IN, + TASKFILE_OUT, + TASKFILE_IN_DMA, + TASKFILE_OUT_DMA, +}; + +static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma) { u8 index, lba48, write; - lba48 = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0; - write = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0; + lba48 = (task->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0; + write = (task->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0; - if (dma) { - cmd->protocol = ATA_PROT_DMA; + if (dma) index = 8; - } else { - cmd->protocol = ATA_PROT_PIO; - if (drive->mult_count) { - cmd->tf_flags |= IDE_TFLAG_MULTI_PIO; - index = 0; - } else - index = 4; - } + else + index = drive->mult_count ? 0 : 4; + + task->tf.command = ide_rw_cmds[index + lba48 + write]; + + if (dma) + index = 8; /* fixup index */ - cmd->tf.command = ide_rw_cmds[index + lba48 + write]; + task->data_phase = ide_data_phases[index / 2 + write]; } /* @@ -85,8 +93,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, u16 nsectors = (u16)rq->nr_sectors; u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t task; + struct ide_taskfile *tf = &task.tf; ide_startstop_t rc; if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) { @@ -96,8 +104,13 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, lba48 = 0; } - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + if (!dma) { + ide_init_sg_cmd(drive, rq); + ide_map_sg(drive, rq); + } + + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; if (drive->dev_flags & IDE_DFLAG_LBA) { if (lba48) { @@ -116,7 +129,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, tf->lbam = (u8)(block >> 8); tf->lbah = (u8)(block >> 16); - cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); + task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); } else { tf->nsect = nsectors & 0xff; tf->lbal = block; @@ -143,27 +156,23 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, tf->device = head; } - cmd.tf_flags |= IDE_TFLAG_FS; - if (rq_data_dir(rq)) - cmd.tf_flags |= IDE_TFLAG_WRITE; - - ide_tf_set_cmd(drive, &cmd, dma); - cmd.rq = rq; + task.tf_flags |= IDE_TFLAG_WRITE; - if (dma == 0) { - ide_init_sg_cmd(&cmd, nsectors << 9); - ide_map_sg(drive, &cmd); - } + ide_tf_set_cmd(drive, &task, dma); + if (!dma) + hwif->data_phase = task.data_phase; + task.rq = rq; - rc = do_rw_taskfile(drive, &cmd); + rc = do_rw_taskfile(drive, &task); if (rc == ide_stopped && dma) { /* fallback to PIO */ - cmd.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK; - ide_tf_set_cmd(drive, &cmd, 0); - ide_init_sg_cmd(&cmd, nsectors << 9); - rc = do_rw_taskfile(drive, &cmd); + task.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK; + ide_tf_set_cmd(drive, &task, 0); + hwif->data_phase = task.data_phase; + ide_init_sg_cmd(drive, rq); + rc = do_rw_taskfile(drive, &task); } return rc; @@ -184,9 +193,7 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, if (!blk_fs_request(rq)) { blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command"); - if (rq->errors == 0) - rq->errors = -EIO; - ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); + ide_end_request(drive, 0, 0); return ide_stopped; } @@ -209,22 +216,22 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, */ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t args; + struct ide_taskfile *tf = &args.tf; u64 addr = 0; - memset(&cmd, 0, sizeof(cmd)); + /* Create IDE/ATA command request structure */ + memset(&args, 0, sizeof(ide_task_t)); if (lba48) tf->command = ATA_CMD_READ_NATIVE_MAX_EXT; else tf->command = ATA_CMD_READ_NATIVE_MAX; tf->device = ATA_LBA; - - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; if (lba48) - cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); - - ide_no_data_taskfile(drive, &cmd); + args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); + /* submit command request */ + ide_no_data_taskfile(drive, &args); /* if OK, compute maximum address value */ if ((tf->status & 0x01) == 0) @@ -239,13 +246,13 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48) */ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t args; + struct ide_taskfile *tf = &args.tf; u64 addr_set = 0; addr_req--; - - memset(&cmd, 0, sizeof(cmd)); + /* Create IDE/ATA command request structure */ + memset(&args, 0, sizeof(ide_task_t)); tf->lbal = (addr_req >> 0) & 0xff; tf->lbam = (addr_req >>= 8) & 0xff; tf->lbah = (addr_req >>= 8) & 0xff; @@ -259,13 +266,11 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) tf->command = ATA_CMD_SET_MAX; } tf->device |= ATA_LBA; - - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; if (lba48) - cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); - - ide_no_data_taskfile(drive, &cmd); - + args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); + /* submit command request */ + ide_no_data_taskfile(drive, &args); /* if OK, compute maximum address value */ if ((tf->status & 0x01) == 0) addr_set = ide_get_lba_addr(tf, lba48) + 1; @@ -384,24 +389,24 @@ static int ide_disk_get_capacity(ide_drive_t *drive) static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) { ide_drive_t *drive = q->queuedata; - struct ide_cmd *cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC); + ide_task_t *task = kmalloc(sizeof(*task), GFP_ATOMIC); /* FIXME: map struct ide_taskfile on rq->cmd[] */ - BUG_ON(cmd == NULL); + BUG_ON(task == NULL); - memset(cmd, 0, sizeof(*cmd)); + memset(task, 0, sizeof(*task)); if (ata_id_flush_ext_enabled(drive->id) && (drive->capacity64 >= (1UL << 28))) - cmd->tf.command = ATA_CMD_FLUSH_EXT; + task->tf.command = ATA_CMD_FLUSH_EXT; else - cmd->tf.command = ATA_CMD_FLUSH; - cmd->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | - IDE_TFLAG_DYN; - cmd->protocol = ATA_PROT_NODATA; + task->tf.command = ATA_CMD_FLUSH; + task->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | + IDE_TFLAG_DYN; + task->data_phase = TASKFILE_NO_DATA; rq->cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_flags |= REQ_SOFTBARRIER; - rq->special = cmd; + rq->special = task; } ide_devset_get(multcount, mult_count); @@ -451,15 +456,15 @@ static int set_nowerr(ide_drive_t *drive, int arg) static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf.feature = feature; - cmd.tf.nsect = nsect; - cmd.tf.command = ATA_CMD_SET_FEATURES; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + memset(&task, 0, sizeof(task)); + task.tf.feature = feature; + task.tf.nsect = nsect; + task.tf.command = ATA_CMD_SET_FEATURES; + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - return ide_no_data_taskfile(drive, &cmd); + return ide_no_data_taskfile(drive, &task); } static void update_ordered(ide_drive_t *drive) @@ -526,16 +531,15 @@ static int set_wcache(ide_drive_t *drive, int arg) static int do_idedisk_flushcache(ide_drive_t *drive) { - struct ide_cmd cmd; + ide_task_t args; - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(ide_task_t)); if (ata_id_flush_ext_enabled(drive->id)) - cmd.tf.command = ATA_CMD_FLUSH_EXT; + args.tf.command = ATA_CMD_FLUSH_EXT; else - cmd.tf.command = ATA_CMD_FLUSH; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - - return ide_no_data_taskfile(drive, &cmd); + args.tf.command = ATA_CMD_FLUSH; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + return ide_no_data_taskfile(drive, &args); } ide_devset_get(acoustic, acoustic); @@ -707,17 +711,17 @@ static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk) static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk, int on) { - struct ide_cmd cmd; + ide_task_t task; int ret; if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) return 0; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + memset(&task, 0, sizeof(task)); + task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - ret = ide_no_data_taskfile(drive, &cmd); + ret = ide_no_data_taskfile(drive, &task); if (ret) drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; @@ -733,5 +737,6 @@ const struct ide_disk_ops ide_ata_disk_ops = { .init_media = ide_disk_init_media, .set_doorlock = ide_disk_set_doorlock, .do_request = ide_do_rw_disk, + .end_request = ide_end_request, .ioctl = ide_disk_ioctl, }; diff --git a/trunk/drivers/ide/ide-disk_proc.c b/trunk/drivers/ide/ide-disk_proc.c index eaea3bef2073..1f86dcbd2b1c 100644 --- a/trunk/drivers/ide/ide-disk_proc.c +++ b/trunk/drivers/ide/ide-disk_proc.c @@ -1,38 +1,38 @@ #include #include +#include #include "ide-disk.h" static int smart_enable(ide_drive_t *drive) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t args; + struct ide_taskfile *tf = &args.tf; - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(ide_task_t)); tf->feature = ATA_SMART_ENABLE; tf->lbam = ATA_SMART_LBAM_PASS; tf->lbah = ATA_SMART_LBAH_PASS; tf->command = ATA_CMD_SMART; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - - return ide_no_data_taskfile(drive, &cmd); + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + return ide_no_data_taskfile(drive, &args); } static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t args; + struct ide_taskfile *tf = &args.tf; - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(ide_task_t)); tf->feature = sub_cmd; tf->nsect = 0x01; tf->lbam = ATA_SMART_LBAM_PASS; tf->lbah = ATA_SMART_LBAH_PASS; tf->command = ATA_CMD_SMART; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - cmd.protocol = ATA_PROT_PIO; - - return ide_raw_taskfile(drive, &cmd, buf, 1); + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args.data_phase = TASKFILE_IN; + (void) smart_enable(drive); + return ide_raw_taskfile(drive, &args, buf, 1); } static int proc_idedisk_read_cache @@ -67,8 +67,6 @@ static int proc_idedisk_read_smart(char *page, char **start, off_t off, ide_drive_t *drive = (ide_drive_t *)data; int len = 0, i = 0; - (void)smart_enable(drive); - if (get_smart_data(drive, page, sub_cmd) == 0) { unsigned short *val = (unsigned short *) page; char *out = (char *)val + SECTOR_SIZE; diff --git a/trunk/drivers/ide/ide-dma-sff.c b/trunk/drivers/ide/ide-dma-sff.c index 75a9ea2e4c82..123d393658af 100644 --- a/trunk/drivers/ide/ide-dma-sff.c +++ b/trunk/drivers/ide/ide-dma-sff.c @@ -111,7 +111,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set); * May also be invoked from trm290.c */ -int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) +int ide_build_dmatable(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; __le32 *table = (__le32 *)hwif->dmatable_cpu; @@ -120,7 +120,11 @@ int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) struct scatterlist *sg; u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290); - for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) { + hwif->sg_nents = ide_build_sglist(drive, rq); + if (hwif->sg_nents == 0) + return 0; + + for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) { u32 cur_addr, cur_len, xcount, bcount; cur_addr = sg_dma_address(sg); @@ -175,7 +179,6 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable); /** * ide_dma_setup - begin a DMA phase * @drive: target device - * @cmd: command * * Build an IDE DMA PRD (IDE speak for scatter gather table) * and then set up the DMA transfer registers for a device @@ -186,16 +189,17 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable); * is returned. */ -int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +int ide_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->rq; + unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR; u8 dma_stat; /* fall back to pio! */ - if (ide_build_dmatable(drive, cmd) == 0) { - ide_map_sg(drive, cmd); + if (!ide_build_dmatable(drive, rq)) { + ide_map_sg(drive, rq); return 1; } @@ -208,9 +212,9 @@ int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) /* specify r/w */ if (mmio) - writeb(rw, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); else - outb(rw, hwif->dma_base + ATA_DMA_CMD); + outb(reading, hwif->dma_base + ATA_DMA_CMD); /* read DMA status for INTR & ERROR flags */ dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); @@ -224,7 +228,7 @@ int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) EXPORT_SYMBOL_GPL(ide_dma_setup); /** - * ide_dma_sff_timer_expiry - handle a DMA timeout + * dma_timer_expiry - handle a DMA timeout * @drive: Drive that timed out * * An IDE DMA transfer timed out. In the event of an error we ask @@ -237,7 +241,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup); * This can occur if an interrupt is lost or due to hang or bugs. */ -int ide_dma_sff_timer_expiry(ide_drive_t *drive) +static int dma_timer_expiry(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); @@ -261,7 +265,14 @@ int ide_dma_sff_timer_expiry(ide_drive_t *drive) return 0; /* Status is unknown -- reset the bus */ } -EXPORT_SYMBOL_GPL(ide_dma_sff_timer_expiry); + +void ide_dma_exec_cmd(ide_drive_t *drive, u8 command) +{ + /* issue cmd to drive */ + ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD, + dma_timer_expiry); +} +EXPORT_SYMBOL_GPL(ide_dma_exec_cmd); void ide_dma_start(ide_drive_t *drive) { @@ -335,10 +346,10 @@ EXPORT_SYMBOL_GPL(ide_dma_test_irq); const struct ide_dma_ops sff_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = ide_dma_end, .dma_test_irq = ide_dma_test_irq, - .dma_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, diff --git a/trunk/drivers/ide/ide-dma.c b/trunk/drivers/ide/ide-dma.c index 3dbf80c15491..a878f4734f81 100644 --- a/trunk/drivers/ide/ide-dma.c +++ b/trunk/drivers/ide/ide-dma.c @@ -96,13 +96,9 @@ ide_startstop_t ide_dma_intr(ide_drive_t *drive) if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) { if (!dma_stat) { - struct ide_cmd *cmd = &hwif->cmd; + struct request *rq = hwif->rq; - if ((cmd->tf_flags & IDE_TFLAG_FS) == 0) - ide_finish_cmd(drive, cmd, stat); - else - ide_complete_rq(drive, 0, - cmd->rq->nr_sectors << 9); + task_end_request(drive, rq, stat); return ide_stopped; } printk(KERN_ERR "%s: %s: bad DMA status (0x%02x)\n", @@ -110,6 +106,7 @@ ide_startstop_t ide_dma_intr(ide_drive_t *drive) } return ide_error(drive, "dma_intr", stat); } +EXPORT_SYMBOL_GPL(ide_dma_intr); int ide_dma_good_drive(ide_drive_t *drive) { @@ -119,7 +116,7 @@ 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 - * @cmd: command + * @rq: the request holding the sg list * * Perform the DMA mapping magic necessary to access the source or * target buffers of a request via DMA. The lower layers of the @@ -127,29 +124,28 @@ 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) +int ide_build_sglist(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; struct scatterlist *sg = hwif->sg_table; int i; - ide_map_sg(drive, cmd); + ide_map_sg(drive, rq); - if (cmd->tf_flags & IDE_TFLAG_WRITE) - cmd->sg_dma_direction = DMA_TO_DEVICE; + if (rq_data_dir(rq) == READ) + hwif->sg_dma_direction = DMA_FROM_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 { - cmd->orig_sg_nents = cmd->sg_nents; - cmd->sg_nents = i; + hwif->sg_dma_direction = DMA_TO_DEVICE; + + i = dma_map_sg(hwif->dev, sg, hwif->sg_nents, hwif->sg_dma_direction); + if (i) { + hwif->orig_sg_nents = hwif->sg_nents; + hwif->sg_nents = i; } return i; } +EXPORT_SYMBOL_GPL(ide_build_sglist); /** * ide_destroy_dmatable - clean up DMA mapping @@ -165,10 +161,9 @@ int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd) void ide_destroy_dmatable(ide_drive_t *drive) { 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); + dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->orig_sg_nents, + hwif->sg_dma_direction); } EXPORT_SYMBOL_GPL(ide_destroy_dmatable); diff --git a/trunk/drivers/ide/ide-eh.c b/trunk/drivers/ide/ide-eh.c index 11664976eea3..1231b5e486f2 100644 --- a/trunk/drivers/ide/ide-eh.c +++ b/trunk/drivers/ide/ide-eh.c @@ -123,18 +123,8 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat) /* retry only "normal" I/O: */ if (!blk_fs_request(rq)) { - if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { - struct ide_cmd *cmd = rq->special; - - if (cmd) - ide_complete_cmd(drive, cmd, stat, err); - } else if (blk_pm_request(rq)) { - rq->errors = 1; - ide_complete_pm_rq(drive, rq); - return ide_stopped; - } - rq->errors = err; - ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq)); + rq->errors = 1; + ide_end_drive_cmd(drive, stat, err); return ide_stopped; } @@ -146,11 +136,8 @@ static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) { struct request *rq = drive->hwif->rq; - if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) { - if (err <= 0 && rq->errors == 0) - rq->errors = -EIO; - ide_complete_rq(drive, err ? err : 0, ide_rq_bytes(rq)); - } + if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) + ide_end_request(drive, err ? err : 1, 0); } /* needed below */ @@ -175,7 +162,8 @@ static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive) printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name); else { if (time_before(jiffies, hwif->poll_timeout)) { - ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20); + ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, + NULL); /* continue polling */ return ide_started; } @@ -237,7 +225,7 @@ static ide_startstop_t reset_pollfunc(ide_drive_t *drive) if (!OK_STAT(tmp, 0, ATA_BUSY)) { if (time_before(jiffies, hwif->poll_timeout)) { - ide_set_handler(drive, &reset_pollfunc, HZ/20); + ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); /* continue polling */ return ide_started; } @@ -354,7 +342,7 @@ static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi) ndelay(400); hwif->poll_timeout = jiffies + WAIT_WORSTCASE; hwif->polling = 1; - __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20); + __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); spin_unlock_irqrestore(&hwif->lock, flags); return ide_started; } @@ -414,7 +402,7 @@ static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi) udelay(10); hwif->poll_timeout = jiffies + WAIT_WORSTCASE; hwif->polling = 1; - __ide_set_handler(drive, &reset_pollfunc, HZ/20); + __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); /* * Some weird controller like resetting themselves to a strange diff --git a/trunk/drivers/ide/ide-floppy.c b/trunk/drivers/ide/ide-floppy.c index 7ae662334835..317ec62c33d4 100644 --- a/trunk/drivers/ide/ide-floppy.c +++ b/trunk/drivers/ide/ide-floppy.c @@ -61,6 +61,50 @@ */ #define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */ +/* Error code returned in rq->errors to the higher part of the driver. */ +#define IDEFLOPPY_ERROR_GENERAL 101 + +/* + * Used to finish servicing a request. For read/write requests, we will call + * ide_end_request to pass to the next buffer. + */ +static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) +{ + struct ide_disk_obj *floppy = drive->driver_data; + struct request *rq = drive->hwif->rq; + int error; + + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + + switch (uptodate) { + case 0: + error = IDEFLOPPY_ERROR_GENERAL; + break; + + case 1: + error = 0; + break; + + default: + error = uptodate; + } + + if (error) + floppy->failed_pc = NULL; + /* Why does this happen? */ + if (!rq) + return 0; + if (!blk_special_request(rq)) { + /* our real local end request function */ + ide_end_request(drive, uptodate, nsecs); + return 0; + } + rq->errors = error; + /* fixme: need to move this local also */ + ide_end_drive_cmd(drive, 0, 0); + return 0; +} + static void idefloppy_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) { @@ -68,23 +112,22 @@ static void idefloppy_update_buffers(ide_drive_t *drive, struct bio *bio = rq->bio; while ((bio = rq->bio) != NULL) - ide_complete_rq(drive, 0, ide_rq_bytes(rq)); + ide_floppy_end_request(drive, 1, 0); } -static int ide_floppy_callback(ide_drive_t *drive, int dsc) +static void ide_floppy_callback(ide_drive_t *drive, int dsc) { struct ide_disk_obj *floppy = drive->driver_data; struct ide_atapi_pc *pc = drive->pc; - struct request *rq = pc->rq; int uptodate = pc->error ? 0 : 1; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - if (drive->failed_pc == pc) - drive->failed_pc = NULL; + if (floppy->failed_pc == pc) + floppy->failed_pc = NULL; if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || - (rq && blk_pc_request(rq))) + (pc->rq && blk_pc_request(pc->rq))) uptodate = 1; /* FIXME */ else if (pc->c[0] == GPCMD_REQUEST_SENSE) { u8 *buf = pc->buf; @@ -96,22 +139,19 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc) floppy->progress_indication = buf[15] & 0x80 ? (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; - if (drive->failed_pc) - ide_debug_log(IDE_DBG_PC, "pc = %x", - drive->failed_pc->c[0]); + if (floppy->failed_pc) + ide_debug_log(IDE_DBG_PC, "pc = %x, ", + floppy->failed_pc->c[0]); ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x," - "ascq = %x", floppy->sense_key, + "ascq = %x\n", floppy->sense_key, floppy->asc, floppy->ascq); } else printk(KERN_ERR PFX "Error in REQUEST SENSE itself - " "Aborting request!\n"); } - if (blk_special_request(rq)) - rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; - - return uptodate; + ide_floppy_end_request(drive, uptodate, 0); } static void ide_floppy_report_error(struct ide_disk_obj *floppy, @@ -130,15 +170,14 @@ static void ide_floppy_report_error(struct ide_disk_obj *floppy, } -static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, - struct ide_cmd *cmd, - struct ide_atapi_pc *pc) +static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, + struct ide_atapi_pc *pc) { struct ide_disk_obj *floppy = drive->driver_data; - if (drive->failed_pc == NULL && + if (floppy->failed_pc == NULL && pc->c[0] != GPCMD_REQUEST_SENSE) - drive->failed_pc = pc; + floppy->failed_pc = pc; /* Set the current packet command */ drive->pc = pc; @@ -147,18 +186,18 @@ static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) ide_floppy_report_error(floppy, pc); /* Giving up */ - pc->error = IDE_DRV_ERROR_GENERAL; + pc->error = IDEFLOPPY_ERROR_GENERAL; - drive->failed_pc = NULL; + floppy->failed_pc = NULL; drive->pc_callback(drive, 0); return ide_stopped; } - ide_debug_log(IDE_DBG_FUNC, "retry #%d", pc->retries); + ide_debug_log(IDE_DBG_FUNC, "%s: Retry #%d\n", __func__, pc->retries); pc->retries++; - return ide_issue_pc(drive, cmd); + return ide_issue_pc(drive); } void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) @@ -203,7 +242,8 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, int blocks = rq->nr_sectors / floppy->bs_factor; int cmd = rq_data_dir(rq); - ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks); + ide_debug_log(IDE_DBG_FUNC, "%s: block: %d, blocks: %d\n", __func__, + block, blocks); ide_init_pc(pc); pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; @@ -245,34 +285,34 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, { struct ide_disk_obj *floppy = drive->driver_data; ide_hwif_t *hwif = drive->hwif; - struct ide_cmd cmd; struct ide_atapi_pc *pc; - if (drive->debug_mask & IDE_DBG_RQ) - blk_dump_rq_flags(rq, (rq->rq_disk - ? rq->rq_disk->disk_name - : "dev?")); + ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " + "errors: %d\n", + __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?", + rq->cmd[0], rq->cmd_type, rq->errors); + + ide_debug_log(IDE_DBG_FUNC, "%s: sector: %ld, nr_sectors: %ld, " + "current_nr_sectors: %d\n", + __func__, (long)rq->sector, rq->nr_sectors, + rq->current_nr_sectors); if (rq->errors >= ERROR_MAX) { - if (drive->failed_pc) { - ide_floppy_report_error(floppy, drive->failed_pc); - drive->failed_pc = NULL; - } else + if (floppy->failed_pc) + ide_floppy_report_error(floppy, floppy->failed_pc); + else printk(KERN_ERR PFX "%s: I/O error\n", drive->name); - if (blk_special_request(rq)) { - rq->errors = 0; - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); - return ide_stopped; - } else - goto out_end; + ide_floppy_end_request(drive, 0, 0); + return ide_stopped; } if (blk_fs_request(rq)) { if (((long)rq->sector % floppy->bs_factor) || (rq->nr_sectors % floppy->bs_factor)) { printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", drive->name); - goto out_end; + ide_floppy_end_request(drive, 0, 0); + return ide_stopped; } pc = &floppy->queued_pc; idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); @@ -283,33 +323,21 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, idefloppy_blockpc_cmd(floppy, pc, rq); } else { blk_dump_rq_flags(rq, PFX "unsupported command in queue"); - goto out_end; + ide_floppy_end_request(drive, 0, 0); + return ide_stopped; } - memset(&cmd, 0, sizeof(cmd)); - - if (rq_data_dir(rq)) - cmd.tf_flags |= IDE_TFLAG_WRITE; - - cmd.rq = rq; - if (blk_fs_request(rq) || pc->req_xfer) { - ide_init_sg_cmd(&cmd, rq->nr_sectors << 9); - ide_map_sg(drive, &cmd); + ide_init_sg_cmd(drive, rq); + ide_map_sg(drive, rq); } pc->sg = hwif->sg_table; - pc->sg_cnt = cmd.sg_nents; + pc->sg_cnt = hwif->sg_nents; pc->rq = rq; - return ide_floppy_issue_pc(drive, &cmd, pc); -out_end: - drive->failed_pc = NULL; - if (blk_fs_request(rq) == 0 && rq->errors == 0) - rq->errors = -EIO; - ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); - return ide_stopped; + return idefloppy_issue_pc(drive, pc); } /* @@ -410,9 +438,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, " - "%d sector size", - i, blocks * length / 1024, - blocks, length); + "%d sector size\n", + i, blocks * length / 1024, blocks, length); if (i) continue; @@ -468,8 +495,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) "in drive\n", drive->name); break; } - ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d", - pc.buf[desc_start + 4] & 0x03); + ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d\n", + pc.buf[desc_start + 4] & 0x03); } /* Clik! disk does not support get_flexible_disk_page */ @@ -548,5 +575,6 @@ const struct ide_disk_ops ide_atapi_disk_ops = { .init_media = ide_floppy_init_media, .set_doorlock = ide_set_media_lock, .do_request = ide_floppy_do_request, + .end_request = ide_floppy_end_request, .ioctl = ide_floppy_ioctl, }; diff --git a/trunk/drivers/ide/ide-gd.c b/trunk/drivers/ide/ide-gd.c index 1aebdf1a4f58..047109419902 100644 --- a/trunk/drivers/ide/ide-gd.c +++ b/trunk/drivers/ide/ide-gd.c @@ -145,6 +145,11 @@ static ide_startstop_t ide_gd_do_request(ide_drive_t *drive, return drive->disk_ops->do_request(drive, rq, sector); } +static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs) +{ + return drive->disk_ops->end_request(drive, uptodate, nrsecs); +} + static struct ide_driver ide_gd_driver = { .gen_driver = { .owner = THIS_MODULE, @@ -157,6 +162,7 @@ static struct ide_driver ide_gd_driver = { .shutdown = ide_gd_shutdown, .version = IDE_GD_VERSION, .do_request = ide_gd_do_request, + .end_request = ide_gd_end_request, #ifdef CONFIG_IDE_PROC_FS .proc_entries = ide_disk_proc_entries, .proc_devsets = ide_disk_proc_devsets, @@ -176,7 +182,7 @@ static int ide_gd_open(struct block_device *bdev, fmode_t mode) drive = idkp->drive; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); idkp->openers++; @@ -226,7 +232,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode) struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); if (idkp->openers == 1) drive->disk_ops->flush(drive); diff --git a/trunk/drivers/ide/ide-gd.h b/trunk/drivers/ide/ide-gd.h index 55970772bd04..b604bdd318a1 100644 --- a/trunk/drivers/ide/ide-gd.h +++ b/trunk/drivers/ide/ide-gd.h @@ -8,7 +8,7 @@ #define IDE_GD_DEBUG_LOG 0 #if IDE_GD_DEBUG_LOG -#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args) +#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) #else #define ide_debug_log(lvl, fmt, args...) do {} while (0) #endif @@ -20,6 +20,8 @@ struct ide_disk_obj { struct device dev; unsigned int openers; /* protected by BKL for now */ + /* Last failed packet command */ + struct ide_atapi_pc *failed_pc; /* used for blk_{fs,pc}_request() requests */ struct ide_atapi_pc queued_pc; diff --git a/trunk/drivers/ide/ide-generic.c b/trunk/drivers/ide/ide-generic.c index 9d03e8211536..81a5282ce1eb 100644 --- a/trunk/drivers/ide/ide-generic.c +++ b/trunk/drivers/ide/ide-generic.c @@ -32,10 +32,6 @@ static int probe_mask; module_param(probe_mask, int, 0); MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports"); -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; @@ -50,7 +46,7 @@ static ssize_t store_add(struct class *cls, const char *buf, size_t n) hw.irq = irq; hw.chipset = ide_generic; - rc = ide_host_add(&ide_generic_port_info, hws, NULL); + rc = ide_host_add(NULL, hws, NULL); if (rc) return rc; @@ -188,7 +184,7 @@ static int __init ide_generic_init(void) #endif hw.chipset = ide_generic; - rc = ide_host_add(&ide_generic_port_info, hws, NULL); + rc = ide_host_add(NULL, hws, NULL); if (rc) { release_region(io_addr + 0x206, 1); release_region(io_addr, 8); diff --git a/trunk/drivers/ide/ide-h8300.c b/trunk/drivers/ide/ide-h8300.c index ff8339ed59ab..9270d3255ee0 100644 --- a/trunk/drivers/ide/ide-h8300.c +++ b/trunk/drivers/ide/ide-h8300.c @@ -44,53 +44,53 @@ static u16 mm_inw(unsigned long a) return r; } -static void h8300_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; - u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) + if (task->tf_flags & IDE_TFLAG_OUT_DATA) mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) outb(tf->hob_feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } -static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; - if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) { + if (task->tf_flags & IDE_TFLAG_IN_DATA) { u16 data = mm_inw(io_ports->data_addr); tf->data = data & 0xff; @@ -100,31 +100,31 @@ static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) /* be sure we're looking at the low order bits */ outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) tf->feature = inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { + if (task->tf_flags & IDE_TFLAG_LBA48) { outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) tf->hob_feature = inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) tf->hob_nsect = inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) tf->hob_lbal = inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) tf->hob_lbam = inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) tf->hob_lbah = inb(io_ports->lbah_addr); } } @@ -143,13 +143,13 @@ static void mm_insw(unsigned long addr, void *buf, u32 len) *bp = bswap(*(volatile u16 *)addr); } -static void h8300_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void h8300_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); } -static void h8300_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void h8300_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); diff --git a/trunk/drivers/ide/ide-io-std.c b/trunk/drivers/ide/ide-io-std.c index 2d9c6dc3f956..45b43dd49cda 100644 --- a/trunk/drivers/ide/ide-io-std.c +++ b/trunk/drivers/ide/ide-io-std.c @@ -2,13 +2,6 @@ #include #include -#if defined(CONFIG_ARM) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \ - defined(CONFIG_PARISC) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) -#include -#else -#include -#endif - /* * Conventional PIO operations for ATA devices */ @@ -82,24 +75,24 @@ void ide_set_irq(ide_hwif_t *hwif, int on) } EXPORT_SYMBOL_GPL(ide_set_irq); -void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +void ide_tf_load(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; void (*tf_outb)(u8 addr, unsigned long port); u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; + u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; if (mmio) tf_outb = ide_mm_outb; else tf_outb = ide_outb; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) { + if (task->tf_flags & IDE_TFLAG_OUT_DATA) { u16 data = (tf->hob_data << 8) | tf->data; if (mmio) @@ -108,39 +101,39 @@ void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) outw(data, io_ports->data_addr); } - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) + if (task->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) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) tf_outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) tf_outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) tf_outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) tf_outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) tf_outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) tf_outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) tf_outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) tf_outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) tf_outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) tf_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } EXPORT_SYMBOL_GPL(ide_tf_load); -void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +void ide_tf_read(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; void (*tf_outb)(u8 addr, unsigned long port); u8 (*tf_inb)(unsigned long port); u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; @@ -153,7 +146,7 @@ void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) tf_inb = ide_inb; } - if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) { + if (task->tf_flags & IDE_TFLAG_IN_DATA) { u16 data; if (mmio) @@ -168,31 +161,31 @@ void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) /* be sure we're looking at the low order bits */ tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) tf->feature = tf_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = tf_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = tf_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = tf_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = tf_inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = tf_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { + if (task->tf_flags & IDE_TFLAG_LBA48) { tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) tf->hob_feature = tf_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) tf->hob_nsect = tf_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) tf->hob_lbal = tf_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) tf->hob_lbam = tf_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) tf->hob_lbah = tf_inb(io_ports->lbah_addr); } } @@ -219,7 +212,7 @@ static void ata_vlb_sync(unsigned long port) * so if an odd len is specified, be sure that there's at least one * extra byte allocated for the buffer. */ -void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, +void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; @@ -265,7 +258,7 @@ EXPORT_SYMBOL_GPL(ide_input_data); /* * This is used for most PIO data transfers *to* the IDE interface */ -void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, +void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index 1adc5e2e7fb3..2e92497b58aa 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -54,9 +55,25 @@ #include #include -int ide_end_rq(ide_drive_t *drive, struct request *rq, int error, - unsigned int nr_bytes) +static int __ide_end_request(ide_drive_t *drive, struct request *rq, + int uptodate, unsigned int nr_bytes, int dequeue) { + int ret = 1; + int error = 0; + + if (uptodate <= 0) + error = uptodate ? uptodate : -EIO; + + /* + * if failfast is set on a request, override number of sectors and + * complete the whole request right now + */ + if (blk_noretry_request(rq) && error) + nr_bytes = rq->hard_nr_sectors << 9; + + if (!blk_fs_request(rq) && error && !rq->errors) + rq->errors = -EIO; + /* * decide whether to reenable DMA -- 3 is a random magic for now, * if we DMA timeout more than 3 times, just stay in PIO @@ -67,86 +84,127 @@ int ide_end_rq(ide_drive_t *drive, struct request *rq, int error, ide_dma_on(drive); } - return blk_end_request(rq, error, nr_bytes); + if (!blk_end_request(rq, error, nr_bytes)) + ret = 0; + + if (ret == 0 && dequeue) + drive->hwif->rq = NULL; + + return ret; } -EXPORT_SYMBOL_GPL(ide_end_rq); -void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err) +/** + * ide_end_request - complete an IDE I/O + * @drive: IDE device for the I/O + * @uptodate: + * @nr_sectors: number of sectors completed + * + * This is our end_request wrapper function. We complete the I/O + * update random number input and dequeue the request, which if + * it was tagged may be out of order. + */ + +int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) { - struct ide_taskfile *tf = &cmd->tf; - struct request *rq = cmd->rq; - u8 tf_cmd = tf->command; - - tf->error = err; - tf->status = stat; - - drive->hwif->tp_ops->tf_read(drive, cmd); - - if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) && - tf_cmd == ATA_CMD_IDLEIMMEDIATE) { - if (tf->lbal != 0xc4) { - printk(KERN_ERR "%s: head unload failed!\n", - drive->name); - ide_tf_dump(drive->name, tf); - } else - drive->dev_flags |= IDE_DFLAG_PARKED; - } + unsigned int nr_bytes = nr_sectors << 9; + struct request *rq = drive->hwif->rq; - if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE) - memcpy(rq->special, cmd, sizeof(*cmd)); + if (!nr_bytes) { + if (blk_pc_request(rq)) + nr_bytes = rq->data_len; + else + nr_bytes = rq->hard_cur_sectors << 9; + } - if (cmd->tf_flags & IDE_TFLAG_DYN) - kfree(cmd); + return __ide_end_request(drive, rq, uptodate, nr_bytes, 1); } +EXPORT_SYMBOL(ide_end_request); -/* obsolete, blk_rq_bytes() should be used instead */ -unsigned int ide_rq_bytes(struct request *rq) +/** + * ide_end_dequeued_request - complete an IDE I/O + * @drive: IDE device for the I/O + * @uptodate: + * @nr_sectors: number of sectors completed + * + * Complete an I/O that is no longer on the request queue. This + * typically occurs when we pull the request and issue a REQUEST_SENSE. + * We must still finish the old request but we must not tamper with the + * queue in the meantime. + * + * NOTE: This path does not handle barrier, but barrier is not supported + * on ide-cd anyway. + */ + +int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, + int uptodate, int nr_sectors) { - if (blk_pc_request(rq)) - return rq->data_len; - else - return rq->hard_cur_sectors << 9; + BUG_ON(!blk_rq_started(rq)); + + return __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0); } -EXPORT_SYMBOL_GPL(ide_rq_bytes); +EXPORT_SYMBOL_GPL(ide_end_dequeued_request); -int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes) +/** + * ide_end_drive_cmd - end an explicit drive command + * @drive: command + * @stat: status bits + * @err: error bits + * + * Clean up after success/failure of an explicit drive command. + * These get thrown onto the queue so they are synchronized with + * real I/O operations on the drive. + * + * In LBA48 mode we have to read the register set twice to get + * all the extra information out. + */ + +void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) { ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->rq; - int rc; - /* - * if failfast is set on a request, override number of sectors - * and complete the whole request right now - */ - if (blk_noretry_request(rq) && error <= 0) - nr_bytes = rq->hard_nr_sectors << 9; + if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { + ide_task_t *task = (ide_task_t *)rq->special; - rc = ide_end_rq(drive, rq, error, nr_bytes); - if (rc == 0) - hwif->rq = NULL; + if (task) { + struct ide_taskfile *tf = &task->tf; - return rc; + tf->error = err; + tf->status = stat; + + drive->hwif->tp_ops->tf_read(drive, task); + + if (task->tf_flags & IDE_TFLAG_DYN) + kfree(task); + } + } else if (blk_pm_request(rq)) { + struct request_pm_state *pm = rq->data; + + ide_complete_power_step(drive, rq); + if (pm->pm_step == IDE_PM_COMPLETED) + ide_complete_pm_request(drive, rq); + return; + } + + hwif->rq = NULL; + + rq->errors = err; + + if (unlikely(blk_end_request(rq, (rq->errors ? -EIO : 0), + blk_rq_bytes(rq)))) + BUG(); } -EXPORT_SYMBOL(ide_complete_rq); +EXPORT_SYMBOL(ide_end_drive_cmd); void ide_kill_rq(ide_drive_t *drive, struct request *rq) { - u8 drv_req = blk_special_request(rq) && rq->rq_disk; - u8 media = drive->media; - - drive->failed_pc = NULL; + if (rq->rq_disk) { + struct ide_driver *drv; - if ((media == ide_floppy || media == ide_tape) && drv_req) { - rq->errors = 0; - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); - } else { - if (media == ide_tape) - rq->errors = IDE_DRV_ERROR_GENERAL; - else if (blk_fs_request(rq) == 0 && rq->errors == 0) - rq->errors = -EIO; - ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); - } + drv = *(struct ide_driver **)rq->rq_disk->private_data; + drv->end_request(drive, 0, 0); + } else + ide_end_request(drive, 0, 0); } static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) @@ -174,20 +232,20 @@ static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf) static ide_startstop_t ide_disk_special(ide_drive_t *drive) { special_t *s = &drive->special; - struct ide_cmd cmd; + ide_task_t args; - memset(&cmd, 0, sizeof(cmd)); - cmd.protocol = ATA_PROT_NODATA; + memset(&args, 0, sizeof(ide_task_t)); + args.data_phase = TASKFILE_NO_DATA; if (s->b.set_geometry) { s->b.set_geometry = 0; - ide_tf_set_specify_cmd(drive, &cmd.tf); + ide_tf_set_specify_cmd(drive, &args.tf); } else if (s->b.recalibrate) { s->b.recalibrate = 0; - ide_tf_set_restore_cmd(drive, &cmd.tf); + ide_tf_set_restore_cmd(drive, &args.tf); } else if (s->b.set_multmode) { s->b.set_multmode = 0; - ide_tf_set_setmult_cmd(drive, &cmd.tf); + ide_tf_set_setmult_cmd(drive, &args.tf); } else if (s->all) { int special = s->all; s->all = 0; @@ -195,10 +253,10 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) return ide_stopped; } - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE | - IDE_TFLAG_CUSTOM_HANDLER; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE | + IDE_TFLAG_CUSTOM_HANDLER; - do_rw_taskfile(drive, &cmd); + do_rw_taskfile(drive, &args); return ide_started; } @@ -228,29 +286,33 @@ static ide_startstop_t do_special (ide_drive_t *drive) return ide_stopped; } -void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) +void ide_map_sg(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; struct scatterlist *sg = hwif->sg_table; - struct request *rq = cmd->rq; if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE); - cmd->sg_nents = 1; + hwif->sg_nents = 1; } else if (!rq->bio) { sg_init_one(sg, rq->data, rq->data_len); - cmd->sg_nents = 1; - } else - cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); + hwif->sg_nents = 1; + } else { + hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); + } } + EXPORT_SYMBOL_GPL(ide_map_sg); -void ide_init_sg_cmd(struct ide_cmd *cmd, unsigned int nr_bytes) +void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq) { - cmd->nbytes = cmd->nleft = nr_bytes; - cmd->cursg_ofs = 0; - cmd->cursg = NULL; + ide_hwif_t *hwif = drive->hwif; + + hwif->nsect = hwif->nleft = rq->nr_sectors; + hwif->cursg_ofs = 0; + hwif->cursg = NULL; } + EXPORT_SYMBOL_GPL(ide_init_sg_cmd); /** @@ -268,15 +330,24 @@ EXPORT_SYMBOL_GPL(ide_init_sg_cmd); static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq) { - struct ide_cmd *cmd = rq->special; - - if (cmd) { - if (cmd->protocol == ATA_PROT_PIO) { - ide_init_sg_cmd(cmd, rq->nr_sectors << 9); - ide_map_sg(drive, cmd); + ide_hwif_t *hwif = drive->hwif; + ide_task_t *task = rq->special; + + if (task) { + hwif->data_phase = task->data_phase; + + switch (hwif->data_phase) { + case TASKFILE_MULTI_OUT: + case TASKFILE_OUT: + case TASKFILE_MULTI_IN: + case TASKFILE_IN: + ide_init_sg_cmd(drive, rq); + ide_map_sg(drive, rq); + default: + break; } - return do_rw_taskfile(drive, cmd); + return do_rw_taskfile(drive, task); } /* @@ -286,8 +357,8 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, #ifdef DEBUG printk("%s: DRIVE_CMD (null)\n", drive->name); #endif - rq->errors = 0; - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); + ide_end_drive_cmd(drive, hwif->tp_ops->read_status(hwif), + ide_read_error(drive)); return ide_stopped; } @@ -305,7 +376,9 @@ static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) case REQ_DRIVE_RESET: return ide_do_reset(drive); default: - BUG(); + blk_dump_rq_flags(rq, "ide_special_rq - bad request"); + ide_end_request(drive, 0, 0); + return ide_stopped; } } @@ -365,7 +438,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) startstop = ide_start_power_step(drive, rq); if (startstop == ide_stopped && pm->pm_step == IDE_PM_COMPLETED) - ide_complete_pm_rq(drive, rq); + ide_complete_pm_request(drive, rq); return startstop; } else if (!rq->rq_disk && blk_special_request(rq)) /* @@ -428,8 +501,8 @@ static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif) if (host->host_flags & IDE_HFLAG_SERIALIZE) { rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy); if (rc == 0) { - if (host->get_lock) - host->get_lock(ide_intr, hwif); + /* for atari only */ + ide_get_lock(ide_intr, hwif); } } return rc; @@ -438,8 +511,8 @@ static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif) static inline void ide_unlock_host(struct ide_host *host) { if (host->host_flags & IDE_HFLAG_SERIALIZE) { - if (host->release_lock) - host->release_lock(); + /* for atari only */ + ide_release_lock(); clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy); } } @@ -651,7 +724,6 @@ void ide_timer_expiry (unsigned long data) } } hwif->handler = NULL; - hwif->expiry = NULL; /* * We need to simulate a real interrupt when invoking * the handler() function, which means we need to @@ -667,8 +739,7 @@ void ide_timer_expiry (unsigned long data) } else if (drive_is_ready(drive)) { if (drive->waiting_for_dma) hwif->dma_ops->dma_lost_irq(drive); - if (hwif->ack_intr) - hwif->ack_intr(hwif); + (void)ide_ack_intr(hwif); printk(KERN_WARNING "%s: lost interrupt\n", drive->name); startstop = handler(drive); @@ -769,7 +840,6 @@ static void unexpected_intr(int irq, ide_hwif_t *hwif) irqreturn_t ide_intr (int irq, void *dev_id) { ide_hwif_t *hwif = (ide_hwif_t *)dev_id; - struct ide_host *host = hwif->host; ide_drive_t *uninitialized_var(drive); ide_handler_t *handler; unsigned long flags; @@ -777,14 +847,14 @@ irqreturn_t ide_intr (int irq, void *dev_id) irqreturn_t irq_ret = IRQ_NONE; int plug_device = 0; - if (host->host_flags & IDE_HFLAG_SERIALIZE) { - if (hwif != host->cur_port) + if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) { + if (hwif != hwif->host->cur_port) goto out_early; } spin_lock_irqsave(&hwif->lock, flags); - if (hwif->ack_intr && hwif->ack_intr(hwif) == 0) + if (!ide_ack_intr(hwif)) goto out; handler = hwif->handler; @@ -801,19 +871,27 @@ irqreturn_t ide_intr (int irq, void *dev_id) * * For PCI, we cannot tell the difference, * so in that case we just ignore it and hope it goes away. + * + * FIXME: unexpected_intr should be hwif-> then we can + * remove all the ifdef PCI crap */ - if ((host->irq_flags & IRQF_SHARED) == 0) { +#ifdef CONFIG_BLK_DEV_IDEPCI + if (hwif->chipset != ide_pci) +#endif /* CONFIG_BLK_DEV_IDEPCI */ + { /* * Probably not a shared PCI interrupt, * so we can safely try to do something about it: */ unexpected_intr(irq, hwif); +#ifdef CONFIG_BLK_DEV_IDEPCI } else { /* * Whack the status register, just in case * we have a leftover pending IRQ. */ (void)hwif->tp_ops->read_status(hwif); +#endif /* CONFIG_BLK_DEV_IDEPCI */ } goto out; } @@ -831,7 +909,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) goto out; hwif->handler = NULL; - hwif->expiry = NULL; hwif->req_gen++; del_timer(&hwif->timer); spin_unlock(&hwif->lock); diff --git a/trunk/drivers/ide/ide-ioctls.c b/trunk/drivers/ide/ide-ioctls.c index 770142767437..1be263eb9c07 100644 --- a/trunk/drivers/ide/ide-ioctls.c +++ b/trunk/drivers/ide/ide-ioctls.c @@ -111,13 +111,13 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) return 0; } -static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) +static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg) { u8 *buf = NULL; int bufsize = 0, err = 0; u8 args[4], xfer_rate = 0; - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t tfargs; + struct ide_taskfile *tf = &tfargs.tf; u16 *id = drive->id; if (NULL == (void *) arg) { @@ -134,24 +134,24 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) if (copy_from_user(args, (void __user *)arg, 4)) return -EFAULT; - memset(&cmd, 0, sizeof(cmd)); + memset(&tfargs, 0, sizeof(ide_task_t)); tf->feature = args[2]; if (args[0] == ATA_CMD_SMART) { tf->nsect = args[3]; tf->lbal = args[1]; tf->lbam = 0x4f; tf->lbah = 0xc2; - cmd.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT; + tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT; } else { tf->nsect = args[1]; - cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT | - IDE_TFLAG_IN_NSECT; + tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE | + IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT; } tf->command = args[0]; - cmd.protocol = args[3] ? ATA_PROT_PIO : ATA_PROT_NODATA; + tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA; if (args[3]) { - cmd.tf_flags |= IDE_TFLAG_IO_16BIT; + tfargs.tf_flags |= IDE_TFLAG_IO_16BIT; bufsize = SECTOR_SIZE * args[3]; buf = kzalloc(bufsize, GFP_KERNEL); if (buf == NULL) @@ -172,7 +172,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) } } - err = ide_raw_taskfile(drive, &cmd, buf, args[3]); + err = ide_raw_taskfile(drive, &tfargs, buf, args[3]); args[0] = tf->status; args[1] = tf->error; @@ -194,25 +194,25 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) return err; } -static int ide_task_ioctl(ide_drive_t *drive, unsigned long arg) +static int ide_task_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg) { void __user *p = (void __user *)arg; int err = 0; u8 args[7]; - struct ide_cmd cmd; + ide_task_t task; if (copy_from_user(args, p, 7)) return -EFAULT; - memset(&cmd, 0, sizeof(cmd)); - memcpy(&cmd.tf_array[7], &args[1], 6); - cmd.tf.command = args[0]; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + memset(&task, 0, sizeof(task)); + memcpy(&task.tf_array[7], &args[1], 6); + task.tf.command = args[0]; + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - err = ide_no_data_taskfile(drive, &cmd); + err = ide_no_data_taskfile(drive, &task); - args[0] = cmd.tf.command; - memcpy(&args[1], &cmd.tf_array[7], 6); + args[0] = task.tf.command; + memcpy(&args[1], &task.tf_array[7], 6); if (copy_to_user(p, args, 7)) err = -EFAULT; @@ -262,17 +262,17 @@ int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev, if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; if (drive->media == ide_disk) - return ide_taskfile_ioctl(drive, arg); + return ide_taskfile_ioctl(drive, cmd, arg); return -ENOMSG; #endif case HDIO_DRIVE_CMD: if (!capable(CAP_SYS_RAWIO)) return -EACCES; - return ide_cmd_ioctl(drive, arg); + return ide_cmd_ioctl(drive, cmd, arg); case HDIO_DRIVE_TASK: if (!capable(CAP_SYS_RAWIO)) return -EACCES; - return ide_task_ioctl(drive, arg); + return ide_task_ioctl(drive, cmd, arg); case HDIO_DRIVE_RESET: if (!capable(CAP_SYS_ADMIN)) return -EACCES; diff --git a/trunk/drivers/ide/ide-iops.c b/trunk/drivers/ide/ide-iops.c index 5403e4a44be4..317c5dadd7c0 100644 --- a/trunk/drivers/ide/ide-iops.c +++ b/trunk/drivers/ide/ide-iops.c @@ -31,15 +31,15 @@ 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; + ide_task_t task; if (port_ops && port_ops->selectproc) port_ops->selectproc(drive); - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_OUT_DEVICE; + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_OUT_DEVICE; - drive->hwif->tp_ops->tf_load(drive, &cmd); + drive->hwif->tp_ops->tf_load(drive, &task); } void SELECT_MASK(ide_drive_t *drive, int mask) @@ -52,14 +52,14 @@ void SELECT_MASK(ide_drive_t *drive, int mask) u8 ide_read_error(ide_drive_t *drive) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_IN_FEATURE; + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_IN_FEATURE; - drive->hwif->tp_ops->tf_read(drive, &cmd); + drive->hwif->tp_ops->tf_read(drive, &task); - return cmd.tf.error; + return task.tf.error; } EXPORT_SYMBOL_GPL(ide_read_error); @@ -329,7 +329,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) u16 *id = drive->id, i; int error = 0; u8 stat; - struct ide_cmd cmd; + ide_task_t task; #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_ops) /* check if host supports DMA */ @@ -361,12 +361,12 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) udelay(1); tp_ops->set_irq(hwif, 0); - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT; - cmd.tf.feature = SETFEATURES_XFER; - cmd.tf.nsect = speed; + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT; + task.tf.feature = SETFEATURES_XFER; + task.tf.nsect = speed; - tp_ops->tf_load(drive, &cmd); + tp_ops->tf_load(drive, &task); tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES); @@ -425,25 +425,26 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) * See also ide_execute_command */ void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler, - unsigned int timeout) + unsigned int timeout, ide_expiry_t *expiry) { ide_hwif_t *hwif = drive->hwif; BUG_ON(hwif->handler); hwif->handler = handler; + hwif->expiry = expiry; hwif->timer.expires = jiffies + timeout; hwif->req_gen_timer = hwif->req_gen; add_timer(&hwif->timer); } -void ide_set_handler(ide_drive_t *drive, ide_handler_t *handler, - unsigned int timeout) +void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, + unsigned int timeout, ide_expiry_t *expiry) { ide_hwif_t *hwif = drive->hwif; unsigned long flags; spin_lock_irqsave(&hwif->lock, flags); - __ide_set_handler(drive, handler, timeout); + __ide_set_handler(drive, handler, timeout, expiry); spin_unlock_irqrestore(&hwif->lock, flags); } EXPORT_SYMBOL(ide_set_handler); @@ -451,9 +452,10 @@ EXPORT_SYMBOL(ide_set_handler); /** * ide_execute_command - execute an IDE command * @drive: IDE drive to issue the command against - * @cmd: command + * @command: command byte to write * @handler: handler for next phase * @timeout: timeout for command + * @expiry: handler to run on timeout * * Helper function to issue an IDE command. This handles the * atomicity requirements, command timing and ensures that the @@ -461,18 +463,15 @@ EXPORT_SYMBOL(ide_set_handler); * should go via this function or do equivalent locking. */ -void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd, - ide_handler_t *handler, unsigned timeout) +void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, + unsigned timeout, ide_expiry_t *expiry) { ide_hwif_t *hwif = drive->hwif; unsigned long flags; spin_lock_irqsave(&hwif->lock, flags); - if ((cmd->protocol != ATAPI_PROT_DMA && - cmd->protocol != ATAPI_PROT_PIO) || - (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT)) - __ide_set_handler(drive, handler, timeout); - hwif->tp_ops->exec_command(hwif, cmd->tf.command); + __ide_set_handler(drive, handler, timeout, expiry); + hwif->tp_ops->exec_command(hwif, cmd); /* * Drive takes 400nS to respond, we must avoid the IRQ being * serviced before that. @@ -482,6 +481,19 @@ void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd, ndelay(400); spin_unlock_irqrestore(&hwif->lock, flags); } +EXPORT_SYMBOL(ide_execute_command); + +void ide_execute_pkt_cmd(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + unsigned long flags; + + spin_lock_irqsave(&hwif->lock, flags); + hwif->tp_ops->exec_command(hwif, ATA_CMD_PACKET); + ndelay(400); + spin_unlock_irqrestore(&hwif->lock, flags); +} +EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); /* * ide_wait_not_busy() waits for the currently selected device on the hwif diff --git a/trunk/drivers/ide/ide-lib.c b/trunk/drivers/ide/ide-lib.c index 217b7fdf2b17..f6c683dd2987 100644 --- a/trunk/drivers/ide/ide-lib.c +++ b/trunk/drivers/ide/ide-lib.c @@ -34,19 +34,19 @@ void ide_toggle_bounce(ide_drive_t *drive, int on) static void ide_dump_opcode(ide_drive_t *drive) { struct request *rq = drive->hwif->rq; - struct ide_cmd *cmd = NULL; + ide_task_t *task = NULL; if (!rq) return; if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) - cmd = rq->special; + task = rq->special; printk(KERN_ERR "ide: failed opcode was: "); - if (cmd == NULL) + if (task == NULL) printk(KERN_CONT "unknown\n"); else - printk(KERN_CONT "0x%02x\n", cmd->tf.command); + printk(KERN_CONT "0x%02x\n", task->tf.command); } u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48) @@ -66,18 +66,18 @@ EXPORT_SYMBOL_GPL(ide_get_lba_addr); static void ide_dump_sector(ide_drive_t *drive) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t task; + struct ide_taskfile *tf = &task.tf; u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); - memset(&cmd, 0, sizeof(cmd)); + memset(&task, 0, sizeof(task)); if (lba48) - cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA | + task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA | IDE_TFLAG_LBA48; else - cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE; + task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE; - drive->hwif->tp_ops->tf_read(drive, &cmd); + drive->hwif->tp_ops->tf_read(drive, &task); if (lba48 || (tf->device & ATA_LBA)) printk(KERN_CONT ", LBAsect=%llu", diff --git a/trunk/drivers/ide/ide-park.c b/trunk/drivers/ide/ide-park.c index 9490b446519f..f30e52152fcb 100644 --- a/trunk/drivers/ide/ide-park.c +++ b/trunk/drivers/ide/ide-park.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -62,10 +63,10 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t task; + struct ide_taskfile *tf = &task.tf; - memset(&cmd, 0, sizeof(cmd)); + memset(&task, 0, sizeof(task)); if (rq->cmd[0] == REQ_PARK_HEADS) { drive->sleep = *(unsigned long *)rq->special; drive->dev_flags |= IDE_DFLAG_SLEEPING; @@ -74,16 +75,14 @@ ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq) tf->lbal = 0x4c; tf->lbam = 0x4e; tf->lbah = 0x55; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER; } else /* cmd == REQ_UNPARK_HEADS */ tf->command = ATA_CMD_CHK_POWER; - cmd.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER; - cmd.protocol = ATA_PROT_NODATA; - - cmd.rq = rq; - - return do_rw_taskfile(drive, &cmd); + task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + task.rq = rq; + drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA; + return do_rw_taskfile(drive, &task); } ssize_t ide_park_show(struct device *dev, struct device_attribute *attr, diff --git a/trunk/drivers/ide/ide-pm.c b/trunk/drivers/ide/ide-pm.c index ebf2d21ebdcb..60538d9c84ee 100644 --- a/trunk/drivers/ide/ide-pm.c +++ b/trunk/drivers/ide/ide-pm.c @@ -1,5 +1,6 @@ #include #include +#include int generic_ide_suspend(struct device *dev, pm_message_t mesg) { @@ -7,7 +8,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; - struct ide_cmd cmd; + ide_task_t args; int ret; /* call ACPI _GTM only once */ @@ -15,10 +16,10 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ide_acpi_get_timing(hwif); memset(&rqpm, 0, sizeof(rqpm)); - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(args)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_SUSPEND; - rq->special = &cmd; + rq->special = &args; rq->data = &rqpm; rqpm.pm_step = IDE_PM_START_SUSPEND; if (mesg.event == PM_EVENT_PRETHAW) @@ -41,7 +42,7 @@ int generic_ide_resume(struct device *dev) ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; - struct ide_cmd cmd; + ide_task_t args; int err; /* call ACPI _PS0 / _STM only once */ @@ -53,11 +54,11 @@ int generic_ide_resume(struct device *dev) ide_acpi_exec_tfs(drive); memset(&rqpm, 0, sizeof(rqpm)); - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(args)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_RESUME; rq->cmd_flags |= REQ_PREEMPT; - rq->special = &cmd; + rq->special = &args; rq->data = &rqpm; rqpm.pm_step = IDE_PM_START_RESUME; rqpm.pm_state = PM_EVENT_ON; @@ -108,9 +109,9 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq) ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) { struct request_pm_state *pm = rq->data; - struct ide_cmd *cmd = rq->special; + ide_task_t *args = rq->special; - memset(cmd, 0, sizeof(*cmd)); + memset(args, 0, sizeof(*args)); switch (pm->pm_step) { case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ @@ -123,12 +124,12 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) return ide_stopped; } if (ata_id_flush_ext_enabled(drive->id)) - cmd->tf.command = ATA_CMD_FLUSH_EXT; + args->tf.command = ATA_CMD_FLUSH_EXT; else - cmd->tf.command = ATA_CMD_FLUSH; + args->tf.command = ATA_CMD_FLUSH; goto out_do_tf; case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ - cmd->tf.command = ATA_CMD_STANDBYNOW1; + args->tf.command = ATA_CMD_STANDBYNOW1; goto out_do_tf; case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ ide_set_max_pio(drive); @@ -141,7 +142,7 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) ide_complete_power_step(drive, rq); return ide_stopped; case IDE_PM_IDLE: /* Resume step 2 (idle) */ - cmd->tf.command = ATA_CMD_IDLEIMMEDIATE; + args->tf.command = ATA_CMD_IDLEIMMEDIATE; goto out_do_tf; case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */ /* @@ -159,34 +160,27 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) } pm->pm_step = IDE_PM_COMPLETED; - return ide_stopped; out_do_tf: - cmd->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - cmd->protocol = ATA_PROT_NODATA; - - return do_rw_taskfile(drive, cmd); + args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args->data_phase = TASKFILE_NO_DATA; + return do_rw_taskfile(drive, args); } /** - * ide_complete_pm_rq - end the current Power Management request + * ide_complete_pm_request - end the current Power Management request * @drive: target drive * @rq: request * * This function cleans up the current PM request and stops the queue * if necessary. */ -void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq) +void ide_complete_pm_request(ide_drive_t *drive, struct request *rq) { struct request_queue *q = drive->queue; - struct request_pm_state *pm = rq->data; unsigned long flags; - ide_complete_power_step(drive, rq); - if (pm->pm_step != IDE_PM_COMPLETED) - return; - #ifdef DEBUG_PM printk("%s: completing PM request, %s\n", drive->name, blk_pm_suspend_request(rq) ? "suspend" : "resume"); diff --git a/trunk/drivers/ide/ide-pnp.c b/trunk/drivers/ide/ide-pnp.c index 6e80b774e88a..bac9b392b689 100644 --- a/trunk/drivers/ide/ide-pnp.c +++ b/trunk/drivers/ide/ide-pnp.c @@ -27,10 +27,6 @@ static struct pnp_device_id idepnp_devices[] = { {.id = ""} }; -static const struct ide_port_info ide_pnp_port_info = { - .host_flags = IDE_HFLAG_NO_DMA, -}; - static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { struct ide_host *host; @@ -64,7 +60,7 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) hw.irq = pnp_irq(dev, 0); hw.chipset = ide_generic; - rc = ide_host_add(&ide_pnp_port_info, hws, &host); + rc = ide_host_add(NULL, hws, &host); if (rc) goto out; diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index 548864510ba9..974067043fba 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -228,9 +228,15 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id) m[ATA_ID_PROD_LEN - 1] = '\0'; if (strstr(m, "E X A B Y T E N E S T")) - drive->dev_flags &= ~IDE_DFLAG_PRESENT; - else - drive->dev_flags |= IDE_DFLAG_PRESENT; + goto err_misc; + + drive->dev_flags |= IDE_DFLAG_PRESENT; + drive->dev_flags &= ~IDE_DFLAG_DEAD; + + return; +err_misc: + kfree(id); + drive->dev_flags &= ~IDE_DFLAG_PRESENT; } /** @@ -283,13 +289,13 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) * identify command to be sure of reply */ if (cmd == ATA_CMD_ID_ATAPI) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); + memset(&task, 0, sizeof(task)); /* disable DMA & overlap */ - cmd.tf_flags = IDE_TFLAG_OUT_FEATURE; + task.tf_flags = IDE_TFLAG_OUT_FEATURE; - tp_ops->tf_load(drive, &cmd); + tp_ops->tf_load(drive, &task); } /* ask drive for ID */ @@ -337,14 +343,14 @@ int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus) static u8 ide_read_device(ide_drive_t *drive) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_IN_DEVICE; + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_IN_DEVICE; - drive->hwif->tp_ops->tf_read(drive, &cmd); + drive->hwif->tp_ops->tf_read(drive, &task); - return cmd.tf.device; + return task.tf.device; } /** @@ -499,7 +505,8 @@ static u8 probe_for_drive(ide_drive_t *drive) } if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) - goto out_free; + /* drive not found */ + return 0; /* identification failed? */ if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { @@ -523,7 +530,7 @@ static u8 probe_for_drive(ide_drive_t *drive) } if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) - goto out_free; + return 0; /* The drive wasn't being helpful. Add generic info only */ if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { @@ -536,10 +543,7 @@ static u8 probe_for_drive(ide_drive_t *drive) ide_disk_init_mult_count(drive); } - return 1; -out_free: - kfree(drive->id); - return 0; + return !!(drive->dev_flags & IDE_DFLAG_PRESENT); } static void hwif_release_dev(struct device *dev) @@ -837,19 +841,34 @@ static int ide_port_setup_devices(ide_hwif_t *hwif) static int init_irq (ide_hwif_t *hwif) { struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_host *host = hwif->host; - irq_handler_t irq_handler = host->irq_handler; - int sa = host->irq_flags; + irq_handler_t irq_handler; + int sa = 0; + irq_handler = hwif->host->irq_handler; if (irq_handler == NULL) irq_handler = ide_intr; +#if defined(__mc68000__) + sa = IRQF_SHARED; +#endif /* __mc68000__ */ + + if (hwif->chipset == ide_pci) + sa = IRQF_SHARED; + if (io_ports->ctl_addr) hwif->tp_ops->set_irq(hwif, 1); if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif)) goto out_up; + if (!hwif->rqsize) { + if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) || + (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA)) + hwif->rqsize = 256; + else + hwif->rqsize = 65536; + } + #if !defined(__mc68000__) printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name, io_ports->data_addr, io_ports->status_addr, @@ -1061,7 +1080,7 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, hwif->tp_ops = d->tp_ops; /* ->set_pio_mode for DTC2278 is currently limited to port 0 */ - if ((hwif->host_flags & IDE_HFLAG_DTC2278) == 0 || hwif->channel == 0) + if (hwif->chipset != ide_dtc2278 || hwif->channel == 0) hwif->port_ops = d->port_ops; hwif->swdma_mask = d->swdma_mask; @@ -1095,13 +1114,6 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, if (d->max_sectors) hwif->rqsize = d->max_sectors; - else { - if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) || - (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA)) - hwif->rqsize = 256; - else - hwif->rqsize = 65536; - } /* call chipset specific routine for each enabled port */ if (d->init_hwif) @@ -1314,8 +1326,6 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) if (d) { host->init_chipset = d->init_chipset; - host->get_lock = d->get_lock; - host->release_lock = d->release_lock; host->host_flags = d->host_flags; } @@ -1362,15 +1372,20 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, ide_init_port_hw(hwif, hws[i]); ide_port_apply_params(hwif); - if ((i & 1) && mate) { - hwif->mate = mate; - mate->mate = hwif; - } + if (d == NULL) { + mate = NULL; + } else { + if ((i & 1) && mate) { + hwif->mate = mate; + mate->mate = hwif; + } + + mate = (i & 1) ? NULL : hwif; - mate = (i & 1) ? NULL : hwif; + ide_init_port(hwif, i & 1, d); + ide_port_cable_detect(hwif); + } - ide_init_port(hwif, i & 1, d); - ide_port_cable_detect(hwif); ide_port_init_devices(hwif); } @@ -1381,8 +1396,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, if (ide_probe_port(hwif) == 0) hwif->present = 1; - if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 || - hwif->mate == NULL || hwif->mate->present == 0) { + if (hwif->chipset != ide_4drives || !hwif->mate || + !hwif->mate->present) { if (ide_register_port(hwif)) { ide_disable_port(hwif); continue; diff --git a/trunk/drivers/ide/ide-proc.c b/trunk/drivers/ide/ide-proc.c index 10a88bf3eefa..417cde56eafd 100644 --- a/trunk/drivers/ide/ide-proc.c +++ b/trunk/drivers/ide/ide-proc.c @@ -194,20 +194,20 @@ ide_devset_get(xfer_rate, current_speed); static int set_xfer_rate (ide_drive_t *drive, int arg) { - struct ide_cmd cmd; + ide_task_t task; int err; if (arg < XFER_PIO_0 || arg > XFER_UDMA_6) return -EINVAL; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf.command = ATA_CMD_SET_FEATURES; - cmd.tf.feature = SETFEATURES_XFER; - cmd.tf.nsect = (u8)arg; - cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT | - IDE_TFLAG_IN_NSECT; + memset(&task, 0, sizeof(task)); + task.tf.command = ATA_CMD_SET_FEATURES; + task.tf.feature = SETFEATURES_XFER; + task.tf.nsect = (u8)arg; + task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT | + IDE_TFLAG_IN_NSECT; - err = ide_no_data_taskfile(drive, &cmd); + err = ide_no_data_taskfile(drive, &task); if (!err) { ide_set_xfer_rate(drive, (u8) arg); diff --git a/trunk/drivers/ide/ide-tape.c b/trunk/drivers/ide/ide-tape.c index 64dfa7458f8d..4e6181c7bbda 100644 --- a/trunk/drivers/ide/ide-tape.c +++ b/trunk/drivers/ide/ide-tape.c @@ -152,6 +152,11 @@ struct idetape_bh { #define IDETAPE_LU_RETENSION_MASK 2 #define IDETAPE_LU_EOT_MASK 4 +/* Error codes returned in rq->errors to the higher part of the driver. */ +#define IDETAPE_ERROR_GENERAL 101 +#define IDETAPE_ERROR_FILEMARK 102 +#define IDETAPE_ERROR_EOD 103 + /* Structures related to the SELECT SENSE / MODE SENSE packet commands. */ #define IDETAPE_BLOCK_DESCRIPTOR 0 #define IDETAPE_CAPABILITIES_PAGE 0x2a @@ -166,6 +171,14 @@ typedef struct ide_tape_obj { struct gendisk *disk; struct device dev; + /* + * failed_pc points to the last failed packet command, or contains + * NULL if we do not need to retry any packet command. This is + * required since an additional packet command is needed before the + * retry, to get detailed information on what went wrong. + */ + /* Last failed packet command */ + struct ide_atapi_pc *failed_pc; /* used by REQ_IDETAPE_{READ,WRITE} requests */ struct ide_atapi_pc queued_pc; @@ -232,6 +245,9 @@ typedef struct ide_tape_obj { /* Wasted space in each stage */ int excess_bh_size; + /* protects the ide-tape queue */ + spinlock_t lock; + /* Measures average tape speed */ unsigned long avg_time; int avg_size; @@ -384,7 +400,7 @@ static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) { idetape_tape_t *tape = drive->driver_data; - struct ide_atapi_pc *pc = drive->failed_pc; + struct ide_atapi_pc *pc = tape->failed_pc; tape->sense_key = sense[2] & 0xF; tape->asc = sense[12]; @@ -417,19 +433,19 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) } } if (pc->c[0] == READ_6 && (sense[2] & 0x80)) { - pc->error = IDE_DRV_ERROR_FILEMARK; + pc->error = IDETAPE_ERROR_FILEMARK; pc->flags |= PC_FLAG_ABORT; } if (pc->c[0] == WRITE_6) { if ((sense[2] & 0x40) || (tape->sense_key == 0xd && tape->asc == 0x0 && tape->ascq == 0x2)) { - pc->error = IDE_DRV_ERROR_EOD; + pc->error = IDETAPE_ERROR_EOD; pc->flags |= PC_FLAG_ABORT; } } if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { if (tape->sense_key == 8) { - pc->error = IDE_DRV_ERROR_EOD; + pc->error = IDETAPE_ERROR_EOD; pc->flags |= PC_FLAG_ABORT; } if (!(pc->flags & PC_FLAG_ABORT) && @@ -461,23 +477,52 @@ static void ide_tape_kfree_buffer(idetape_tape_t *tape) } } +static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) +{ + struct request *rq = drive->hwif->rq; + idetape_tape_t *tape = drive->driver_data; + unsigned long flags; + int error; + + debug_log(DBG_PROCS, "Enter %s\n", __func__); + + switch (uptodate) { + case 0: error = IDETAPE_ERROR_GENERAL; break; + case 1: error = 0; break; + default: error = uptodate; + } + rq->errors = error; + if (error) + tape->failed_pc = NULL; + + if (!blk_special_request(rq)) { + ide_end_request(drive, uptodate, nr_sects); + return 0; + } + + spin_lock_irqsave(&tape->lock, flags); + + ide_end_drive_cmd(drive, 0, 0); + + spin_unlock_irqrestore(&tape->lock, flags); + return 0; +} + static void ide_tape_handle_dsc(ide_drive_t *); -static int ide_tape_callback(ide_drive_t *drive, int dsc) +static void ide_tape_callback(ide_drive_t *drive, int dsc) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc *pc = drive->pc; - struct request *rq = drive->hwif->rq; int uptodate = pc->error ? 0 : 1; - int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; debug_log(DBG_PROCS, "Enter %s\n", __func__); if (dsc) ide_tape_handle_dsc(drive); - if (drive->failed_pc == pc) - drive->failed_pc = NULL; + if (tape->failed_pc == pc) + tape->failed_pc = NULL; if (pc->c[0] == REQUEST_SENSE) { if (uptodate) @@ -486,6 +531,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " "itself - Aborting request!\n"); } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { + struct request *rq = drive->hwif->rq; int blocks = pc->xferred / tape->blk_size; tape->avg_size += blocks * tape->blk_size; @@ -500,10 +546,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) tape->first_frame += blocks; rq->current_nr_sectors -= blocks; - if (pc->error) { - uptodate = 0; - err = pc->error; - } + if (pc->error) + uptodate = pc->error; } else if (pc->c[0] == READ_POSITION && uptodate) { u8 *readpos = pc->buf; @@ -517,7 +561,6 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) "to the tape\n"); clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); uptodate = 0; - err = IDE_DRV_ERROR_GENERAL; } else { debug_log(DBG_SENSE, "Block Location - %u\n", be32_to_cpup((__be32 *)&readpos[4])); @@ -528,9 +571,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) } } - rq->errors = err; - - return uptodate; + idetape_end_request(drive, uptodate, 0); } /* @@ -580,7 +621,7 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, * * The handling will be done in three stages: * - * 1. ide_tape_issue_pc will send the packet command to the drive, and will set + * 1. idetape_issue_pc will send the packet command to the drive, and will set * the interrupt handler to ide_pc_intr. * * 2. On each interrupt, ide_pc_intr will be called. This step will be @@ -608,9 +649,8 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, * request. */ -static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, - struct ide_cmd *cmd, - struct ide_atapi_pc *pc) +static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, + struct ide_atapi_pc *pc) { idetape_tape_t *tape = drive->driver_data; @@ -620,8 +660,8 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, "Two request sense in serial were issued\n"); } - if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) - drive->failed_pc = pc; + if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) + tape->failed_pc = pc; /* Set the current packet command */ drive->pc = pc; @@ -645,9 +685,9 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, tape->ascq); } /* Giving up */ - pc->error = IDE_DRV_ERROR_GENERAL; + pc->error = IDETAPE_ERROR_GENERAL; } - drive->failed_pc = NULL; + tape->failed_pc = NULL; drive->pc_callback(drive, 0); return ide_stopped; } @@ -655,7 +695,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, pc->retries++; - return ide_issue_pc(drive, cmd); + return ide_issue_pc(drive); } /* A mode sense command is used to "sense" tape parameters. */ @@ -706,8 +746,8 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) } pc->error = 0; } else { - pc->error = IDE_DRV_ERROR_GENERAL; - drive->failed_pc = NULL; + pc->error = IDETAPE_ERROR_GENERAL; + tape->failed_pc = NULL; } drive->pc_callback(drive, 0); return ide_stopped; @@ -750,7 +790,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc *pc = NULL; struct request *postponed_rq = tape->postponed_rq; - struct ide_cmd cmd; u8 stat; debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu," @@ -762,15 +801,13 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, /* We do not support buffer cache originated requests. */ printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " "request queue (%d)\n", drive->name, rq->cmd_type); - if (blk_fs_request(rq) == 0 && rq->errors == 0) - rq->errors = -EIO; - ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); + ide_end_request(drive, 0, 0); return ide_stopped; } /* Retry a failed packet command */ - if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { - pc = drive->failed_pc; + if (tape->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { + pc = tape->failed_pc; goto out; } @@ -778,9 +815,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, if (rq != postponed_rq) { printk(KERN_ERR "ide-tape: ide-tape.c bug - " "Two DSC requests were queued\n"); - drive->failed_pc = NULL; - rq->errors = 0; - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); + idetape_end_request(drive, 0, 0); return ide_stopped; } @@ -846,14 +881,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, BUG(); out: - memset(&cmd, 0, sizeof(cmd)); - - if (rq_data_dir(rq)) - cmd.tf_flags |= IDE_TFLAG_WRITE; - - cmd.rq = rq; - - return ide_tape_issue_pc(drive, &cmd, pc); + return idetape_issue_pc(drive, pc); } /* @@ -1198,7 +1226,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, if (tape->merge_bh) idetape_init_merge_buffer(tape); - if (errors == IDE_DRV_ERROR_GENERAL) + if (errors == IDETAPE_ERROR_GENERAL) return -EIO; return ret; } @@ -2164,6 +2192,8 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) drive->pc_update_buffers = idetape_update_buffers; drive->pc_io_buffers = ide_tape_io_buffers; + spin_lock_init(&tape->lock); + drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) { @@ -2295,6 +2325,7 @@ static struct ide_driver idetape_driver = { .remove = ide_tape_remove, .version = IDETAPE_VERSION, .do_request = idetape_do_request, + .end_request = idetape_end_request, #ifdef CONFIG_IDE_PROC_FS .proc_entries = ide_tape_proc_entries, .proc_devsets = ide_tape_proc_devsets, diff --git a/trunk/drivers/ide/ide-taskfile.c b/trunk/drivers/ide/ide-taskfile.c index 84532be97c00..16138bce84a7 100644 --- a/trunk/drivers/ide/ide-taskfile.c +++ b/trunk/drivers/ide/ide-taskfile.c @@ -39,86 +39,88 @@ void ide_tf_dump(const char *s, struct ide_taskfile *tf) int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) { - struct ide_cmd cmd; + ide_task_t args; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf.nsect = 0x01; + memset(&args, 0, sizeof(ide_task_t)); + args.tf.nsect = 0x01; if (drive->media == ide_disk) - cmd.tf.command = ATA_CMD_ID_ATA; + args.tf.command = ATA_CMD_ID_ATA; else - cmd.tf.command = ATA_CMD_ID_ATAPI; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - cmd.protocol = ATA_PROT_PIO; - - return ide_raw_taskfile(drive, &cmd, buf, 1); + args.tf.command = ATA_CMD_ID_ATAPI; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args.data_phase = TASKFILE_IN; + return ide_raw_taskfile(drive, &args, buf, 1); } static ide_startstop_t task_no_data_intr(ide_drive_t *); -static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct ide_cmd *); -static ide_startstop_t task_pio_intr(ide_drive_t *); +static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); +static ide_startstop_t task_in_intr(ide_drive_t *); -ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) +ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; - struct ide_cmd *cmd = &hwif->cmd; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; ide_handler_t *handler = NULL; const struct ide_tp_ops *tp_ops = hwif->tp_ops; const struct ide_dma_ops *dma_ops = hwif->dma_ops; - if (orig_cmd->protocol == ATA_PROT_PIO && - (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) && - drive->mult_count == 0) { - printk(KERN_ERR "%s: multimode not set!\n", drive->name); - return ide_stopped; + if (task->data_phase == TASKFILE_MULTI_IN || + task->data_phase == TASKFILE_MULTI_OUT) { + if (!drive->mult_count) { + printk(KERN_ERR "%s: multimode not set!\n", + drive->name); + return ide_stopped; + } } - if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED) - orig_cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS; + if (task->tf_flags & IDE_TFLAG_FLAGGED) + task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS; - memcpy(cmd, orig_cmd, sizeof(*cmd)); + memcpy(&hwif->task, task, sizeof(*task)); - if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { + if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { ide_tf_dump(drive->name, tf); tp_ops->set_irq(hwif, 1); SELECT_MASK(drive, 0); - tp_ops->tf_load(drive, cmd); + tp_ops->tf_load(drive, task); } - switch (cmd->protocol) { - case ATA_PROT_PIO: - if (cmd->tf_flags & IDE_TFLAG_WRITE) { - tp_ops->exec_command(hwif, tf->command); - ndelay(400); /* FIXME */ - return pre_task_out_intr(drive, cmd); - } - handler = task_pio_intr; + switch (task->data_phase) { + case TASKFILE_MULTI_OUT: + case TASKFILE_OUT: + tp_ops->exec_command(hwif, tf->command); + ndelay(400); /* FIXME */ + return pre_task_out_intr(drive, task->rq); + case TASKFILE_MULTI_IN: + case TASKFILE_IN: + handler = task_in_intr; /* fall-through */ - case ATA_PROT_NODATA: + case TASKFILE_NO_DATA: if (handler == NULL) handler = task_no_data_intr; - ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE); + ide_execute_command(drive, tf->command, handler, + WAIT_WORSTCASE, NULL); return ide_started; - case ATA_PROT_DMA: + default: if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 || - ide_build_sglist(drive, cmd) == 0 || - dma_ops->dma_setup(drive, cmd)) + dma_ops->dma_setup(drive)) return ide_stopped; - hwif->expiry = dma_ops->dma_timer_expiry; - ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD); + dma_ops->dma_exec_cmd(drive, tf->command); dma_ops->dma_start(drive); - default: return ide_started; } } EXPORT_SYMBOL_GPL(do_rw_taskfile); +/* + * Handler for commands without a data phase + */ static ide_startstop_t task_no_data_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - struct ide_cmd *cmd = &hwif->cmd; - struct ide_taskfile *tf = &cmd->tf; - int custom = (cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0; + ide_task_t *task = &hwif->task; + struct ide_taskfile *tf = &task->tf; + int custom = (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0; int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1; u8 stat; @@ -140,26 +142,28 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive) } else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) { if ((stat & (ATA_ERR | ATA_DRQ)) == 0) { ide_set_handler(drive, &task_no_data_intr, - WAIT_WORSTCASE); + WAIT_WORSTCASE, NULL); return ide_started; } } return ide_error(drive, "task_no_data_intr", stat); + /* calls ide_end_drive_cmd */ } - if (custom && tf->command == ATA_CMD_SET_MULTI) + if (!custom) + ide_end_drive_cmd(drive, stat, ide_read_error(drive)); + else if (tf->command == ATA_CMD_IDLEIMMEDIATE) { + hwif->tp_ops->tf_read(drive, task); + if (tf->lbal != 0xc4) { + printk(KERN_ERR "%s: head unload failed!\n", + drive->name); + ide_tf_dump(drive->name, tf); + } else + drive->dev_flags |= IDE_DFLAG_PARKED; + ide_end_drive_cmd(drive, stat, ide_read_error(drive)); + } else if (tf->command == ATA_CMD_SET_MULTI) drive->mult_count = drive->mult_req; - if (custom == 0 || tf->command == ATA_CMD_IDLEIMMEDIATE || - tf->command == ATA_CMD_CHK_POWER) { - struct request *rq = hwif->rq; - - if (blk_pm_request(rq)) - ide_complete_pm_rq(drive, rq); - else - ide_finish_cmd(drive, cmd, stat); - } - return ide_stopped; } @@ -188,12 +192,12 @@ 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) +static void ide_pio_sector(ide_drive_t *drive, struct request *rq, + unsigned int write) { ide_hwif_t *hwif = drive->hwif; struct scatterlist *sg = hwif->sg_table; - struct scatterlist *cursg = cmd->cursg; + struct scatterlist *cursg = hwif->cursg; struct page *page; #ifdef CONFIG_HIGHMEM unsigned long flags; @@ -201,14 +205,14 @@ static void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, unsigned int offset; u8 *buf; - cursg = cmd->cursg; + cursg = hwif->cursg; if (!cursg) { cursg = sg; - cmd->cursg = sg; + hwif->cursg = sg; } page = sg_page(cursg); - offset = cursg->offset + cmd->cursg_ofs; + offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE; /* get the current page and offset */ page = nth_page(page, (offset >> PAGE_SHIFT)); @@ -219,19 +223,19 @@ static void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, #endif buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; - cmd->nleft -= nr_bytes; - cmd->cursg_ofs += nr_bytes; + hwif->nleft--; + hwif->cursg_ofs++; - if (cmd->cursg_ofs == cursg->length) { - cmd->cursg = sg_next(cmd->cursg); - cmd->cursg_ofs = 0; + if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) { + hwif->cursg = sg_next(hwif->cursg); + hwif->cursg_ofs = 0; } /* do the actual data transfer */ if (write) - hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes); + hwif->tp_ops->output_data(drive, rq, buf, SECTOR_SIZE); else - hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes); + hwif->tp_ops->input_data(drive, rq, buf, SECTOR_SIZE); kunmap_atomic(buf, KM_BIO_SRC_IRQ); #ifdef CONFIG_HIGHMEM @@ -239,137 +243,188 @@ static void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, #endif } -static void ide_pio_multi(ide_drive_t *drive, struct ide_cmd *cmd, +static void ide_pio_multi(ide_drive_t *drive, struct request *rq, unsigned int write) { unsigned int nsect; - nsect = min_t(unsigned int, cmd->nleft >> 9, drive->mult_count); + nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count); while (nsect--) - ide_pio_bytes(drive, cmd, write, SECTOR_SIZE); + ide_pio_sector(drive, rq, write); } -static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd, - unsigned int write) +static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, + unsigned int write) { u8 saved_io_32bit = drive->io_32bit; - if (cmd->tf_flags & IDE_TFLAG_FS) - cmd->rq->errors = 0; + if (rq->bio) /* fs request */ + rq->errors = 0; - if (cmd->tf_flags & IDE_TFLAG_IO_16BIT) - drive->io_32bit = 0; + if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { + ide_task_t *task = rq->special; + + if (task->tf_flags & IDE_TFLAG_IO_16BIT) + drive->io_32bit = 0; + } touch_softlockup_watchdog(); - if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) - ide_pio_multi(drive, cmd, write); - else - ide_pio_bytes(drive, cmd, write, SECTOR_SIZE); + switch (drive->hwif->data_phase) { + case TASKFILE_MULTI_IN: + case TASKFILE_MULTI_OUT: + ide_pio_multi(drive, rq, write); + break; + default: + ide_pio_sector(drive, rq, write); + break; + } drive->io_32bit = saved_io_32bit; } -static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) +static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, + const char *s, u8 stat) { - if (cmd->tf_flags & IDE_TFLAG_FS) { - int nr_bytes = cmd->nbytes - cmd->nleft; - - if (cmd->protocol == ATA_PROT_PIO && - ((cmd->tf_flags & IDE_TFLAG_WRITE) || cmd->nleft == 0)) { - if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) - nr_bytes -= drive->mult_count << 9; - else - nr_bytes -= SECTOR_SIZE; + if (rq->bio) { + ide_hwif_t *hwif = drive->hwif; + int sectors = hwif->nsect - hwif->nleft; + + switch (hwif->data_phase) { + case TASKFILE_IN: + if (hwif->nleft) + break; + /* fall through */ + case TASKFILE_OUT: + sectors--; + break; + case TASKFILE_MULTI_IN: + if (hwif->nleft) + break; + /* fall through */ + case TASKFILE_MULTI_OUT: + sectors -= drive->mult_count; + default: + break; } - if (nr_bytes > 0) - ide_complete_rq(drive, 0, nr_bytes); + if (sectors > 0) { + struct ide_driver *drv; + + drv = *(struct ide_driver **)rq->rq_disk->private_data; + drv->end_request(drive, 1, sectors); + } } + return ide_error(drive, s, stat); +} + +void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) +{ + if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { + u8 err = ide_read_error(drive); + + ide_end_drive_cmd(drive, stat, err); + return; + } + + if (rq->rq_disk) { + struct ide_driver *drv; + + drv = *(struct ide_driver **)rq->rq_disk->private_data;; + drv->end_request(drive, 1, rq->nr_sectors); + } else + ide_end_request(drive, 1, rq->nr_sectors); } -void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat) +/* + * We got an interrupt on a task_in case, but no errors and no DRQ. + * + * It might be a spurious irq (shared irq), but it might be a + * command that had no output. + */ +static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat) { - struct request *rq = drive->hwif->rq; - u8 err = ide_read_error(drive); + /* Command all done? */ + if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) { + task_end_request(drive, rq, stat); + return ide_stopped; + } - ide_complete_cmd(drive, cmd, stat, err); - rq->errors = err; - ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq)); + /* Assume it was a spurious irq */ + ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); + return ide_started; } /* - * Handler for command with PIO data phase. + * Handler for command with PIO data-in phase (Read/Read Multiple). */ -static ide_startstop_t task_pio_intr(ide_drive_t *drive) +static ide_startstop_t task_in_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - struct ide_cmd *cmd = &drive->hwif->cmd; + struct request *rq = hwif->rq; u8 stat = hwif->tp_ops->read_status(hwif); - u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE); - if (write == 0) { - /* Error? */ - if (stat & ATA_ERR) - goto out_err; + /* Error? */ + if (stat & ATA_ERR) + return task_error(drive, rq, __func__, stat); - /* Didn't want any data? Odd. */ - if ((stat & ATA_DRQ) == 0) { - /* Command all done? */ - if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) - goto out_end; + /* Didn't want any data? Odd. */ + if ((stat & ATA_DRQ) == 0) + return task_in_unexpected(drive, rq, stat); - /* Assume it was a spurious irq */ - goto out_wait; - } - } else { - if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) - goto out_err; + ide_pio_datablock(drive, rq, 0); - /* Deal with unexpected ATA data phase. */ - if (((stat & ATA_DRQ) == 0) ^ (cmd->nleft == 0)) - goto out_err; + /* Are we done? Check status and finish transfer. */ + if (!hwif->nleft) { + stat = wait_drive_not_busy(drive); + if (!OK_STAT(stat, 0, BAD_STAT)) + return task_error(drive, rq, __func__, stat); + task_end_request(drive, rq, stat); + return ide_stopped; } - if (write && cmd->nleft == 0) - goto out_end; - /* Still data left to transfer. */ - ide_pio_datablock(drive, cmd, write); + ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); - /* Are we done? Check status and finish transfer. */ - if (write == 0 && cmd->nleft == 0) { - stat = wait_drive_not_busy(drive); - if (!OK_STAT(stat, 0, BAD_STAT)) - goto out_err; + return ide_started; +} - goto out_end; +/* + * Handler for command with PIO data-out phase (Write/Write Multiple). + */ +static ide_startstop_t task_out_intr (ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->rq; + u8 stat = hwif->tp_ops->read_status(hwif); + + if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) + return task_error(drive, rq, __func__, stat); + + /* Deal with unexpected ATA data phase. */ + if (((stat & ATA_DRQ) == 0) ^ !hwif->nleft) + return task_error(drive, rq, __func__, stat); + + if (!hwif->nleft) { + task_end_request(drive, rq, stat); + return ide_stopped; } -out_wait: + /* Still data left to transfer. */ - ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE); + ide_pio_datablock(drive, rq, 1); + ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); + return ide_started; -out_end: - if ((cmd->tf_flags & IDE_TFLAG_FS) == 0) - ide_finish_cmd(drive, cmd, stat); - else - ide_complete_rq(drive, 0, cmd->rq->nr_sectors << 9); - return ide_stopped; -out_err: - ide_error_cmd(drive, cmd); - return ide_error(drive, __func__, stat); } -static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, - struct ide_cmd *cmd) +static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) { ide_startstop_t startstop; if (ide_wait_stat(&startstop, drive, ATA_DRQ, drive->bad_wstat, WAIT_DRQ)) { printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", - drive->name, - (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "", + drive->name, drive->hwif->data_phase ? "MULT" : "", (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : ""); return startstop; } @@ -377,15 +432,13 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0) local_irq_disable(); - ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE); - - ide_pio_datablock(drive, cmd, 1); + ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); + ide_pio_datablock(drive, rq, 1); return ide_started; } -int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, - u16 nsect) +int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect) { struct request *rq; int error; @@ -403,11 +456,11 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, rq->hard_nr_sectors = rq->nr_sectors = nsect; rq->hard_cur_sectors = rq->current_nr_sectors = nsect; - if (cmd->tf_flags & IDE_TFLAG_WRITE) + if (task->tf_flags & IDE_TFLAG_WRITE) rq->cmd_flags |= REQ_RW; - rq->special = cmd; - cmd->rq = rq; + rq->special = task; + task->rq = rq; error = blk_execute_rq(drive->queue, NULL, rq, 0); blk_put_request(rq); @@ -417,19 +470,19 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, EXPORT_SYMBOL(ide_raw_taskfile); -int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) +int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task) { - cmd->protocol = ATA_PROT_NODATA; + task->data_phase = TASKFILE_NO_DATA; - return ide_raw_taskfile(drive, cmd, NULL, 0); + return ide_raw_taskfile(drive, task, NULL, 0); } EXPORT_SYMBOL_GPL(ide_no_data_taskfile); #ifdef CONFIG_IDE_TASK_IOCTL -int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) +int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) { ide_task_request_t *req_task; - struct ide_cmd cmd; + ide_task_t args; u8 *outbuf = NULL; u8 *inbuf = NULL; u8 *data_buf = NULL; @@ -483,63 +536,53 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) } } - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(ide_task_t)); - memcpy(&cmd.tf_array[0], req_task->hob_ports, - HDIO_DRIVE_HOB_HDR_SIZE - 2); - memcpy(&cmd.tf_array[6], req_task->io_ports, - HDIO_DRIVE_TASK_HDR_SIZE); + memcpy(&args.tf_array[0], req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2); + memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); - cmd.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | - IDE_TFLAG_IN_TF; + args.data_phase = req_task->data_phase; + args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | + IDE_TFLAG_IN_TF; if (drive->dev_flags & IDE_DFLAG_LBA48) - cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB); + args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB); if (req_task->out_flags.all) { - cmd.ftf_flags |= IDE_FTFLAG_FLAGGED; + args.tf_flags |= IDE_TFLAG_FLAGGED; if (req_task->out_flags.b.data) - cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA; + args.tf_flags |= IDE_TFLAG_OUT_DATA; if (req_task->out_flags.b.nsector_hob) - cmd.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT; + args.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT; if (req_task->out_flags.b.sector_hob) - cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL; + args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL; if (req_task->out_flags.b.lcyl_hob) - cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM; + args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM; if (req_task->out_flags.b.hcyl_hob) - cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH; + args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH; if (req_task->out_flags.b.error_feature) - cmd.tf_flags |= IDE_TFLAG_OUT_FEATURE; + args.tf_flags |= IDE_TFLAG_OUT_FEATURE; if (req_task->out_flags.b.nsector) - cmd.tf_flags |= IDE_TFLAG_OUT_NSECT; + args.tf_flags |= IDE_TFLAG_OUT_NSECT; if (req_task->out_flags.b.sector) - cmd.tf_flags |= IDE_TFLAG_OUT_LBAL; + args.tf_flags |= IDE_TFLAG_OUT_LBAL; if (req_task->out_flags.b.lcyl) - cmd.tf_flags |= IDE_TFLAG_OUT_LBAM; + args.tf_flags |= IDE_TFLAG_OUT_LBAM; if (req_task->out_flags.b.hcyl) - cmd.tf_flags |= IDE_TFLAG_OUT_LBAH; + args.tf_flags |= IDE_TFLAG_OUT_LBAH; } else { - cmd.tf_flags |= IDE_TFLAG_OUT_TF; - if (cmd.tf_flags & IDE_TFLAG_LBA48) - cmd.tf_flags |= IDE_TFLAG_OUT_HOB; + args.tf_flags |= IDE_TFLAG_OUT_TF; + if (args.tf_flags & IDE_TFLAG_LBA48) + args.tf_flags |= IDE_TFLAG_OUT_HOB; } if (req_task->in_flags.b.data) - cmd.ftf_flags |= IDE_FTFLAG_IN_DATA; + args.tf_flags |= IDE_TFLAG_IN_DATA; - if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE) { - /* fixup data phase if needed */ - if (req_task->data_phase == TASKFILE_IN_DMAQ || - req_task->data_phase == TASKFILE_IN_DMA) - cmd.tf_flags |= IDE_TFLAG_WRITE; - } - - cmd.protocol = ATA_PROT_DMA; - - switch (req_task->data_phase) { + switch(req_task->data_phase) { case TASKFILE_MULTI_OUT: if (!drive->mult_count) { /* (hs): give up if multcount is not set */ @@ -549,14 +592,11 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) err = -EPERM; goto abort; } - cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; /* fall through */ case TASKFILE_OUT: - cmd.protocol = ATA_PROT_PIO; /* fall through */ case TASKFILE_OUT_DMAQ: case TASKFILE_OUT_DMA: - cmd.tf_flags |= IDE_TFLAG_WRITE; nsect = taskout / SECTOR_SIZE; data_buf = outbuf; break; @@ -569,10 +609,8 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) err = -EPERM; goto abort; } - cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; /* fall through */ case TASKFILE_IN: - cmd.protocol = ATA_PROT_PIO; /* fall through */ case TASKFILE_IN_DMAQ: case TASKFILE_IN_DMA: @@ -580,7 +618,6 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) data_buf = inbuf; break; case TASKFILE_NO_DATA: - cmd.protocol = ATA_PROT_NODATA; break; default: err = -EFAULT; @@ -590,7 +627,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA) nsect = 0; else if (!nsect) { - nsect = (cmd.tf.hob_nsect << 8) | cmd.tf.nsect; + nsect = (args.tf.hob_nsect << 8) | args.tf.nsect; if (!nsect) { printk(KERN_ERR "%s: in/out command without data\n", @@ -600,14 +637,15 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) } } - err = ide_raw_taskfile(drive, &cmd, data_buf, nsect); + if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE) + args.tf_flags |= IDE_TFLAG_WRITE; + + err = ide_raw_taskfile(drive, &args, data_buf, nsect); - memcpy(req_task->hob_ports, &cmd.tf_array[0], - HDIO_DRIVE_HOB_HDR_SIZE - 2); - memcpy(req_task->io_ports, &cmd.tf_array[6], - HDIO_DRIVE_TASK_HDR_SIZE); + memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2); + memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE); - if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) && + if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) && req_task->in_flags.all == 0) { req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; if (drive->dev_flags & IDE_DFLAG_LBA48) diff --git a/trunk/drivers/ide/ide_arm.c b/trunk/drivers/ide/ide_arm.c index cf6385446ece..bdcac94d7c1f 100644 --- a/trunk/drivers/ide/ide_arm.c +++ b/trunk/drivers/ide/ide_arm.c @@ -18,10 +18,6 @@ #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; @@ -45,7 +41,7 @@ static int __init ide_arm_init(void) hw.irq = IDE_ARM_IRQ; hw.chipset = ide_generic; - return ide_host_add(&ide_arm_port_info, hws, NULL); + return ide_host_add(NULL, hws, NULL); } module_init(ide_arm_init); diff --git a/trunk/drivers/ide/it821x.c b/trunk/drivers/ide/it821x.c index 0d4ac65cf949..6b9fc950b4af 100644 --- a/trunk/drivers/ide/it821x.c +++ b/trunk/drivers/ide/it821x.c @@ -508,10 +508,10 @@ static void it821x_quirkproc(ide_drive_t *drive) static struct ide_dma_ops it821x_pass_through_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = it821x_dma_start, .dma_end = it821x_dma_end, .dma_test_irq = ide_dma_test_irq, - .dma_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, diff --git a/trunk/drivers/ide/macide.c b/trunk/drivers/ide/macide.c index 4b1718e83283..3c60064f1d4f 100644 --- a/trunk/drivers/ide/macide.c +++ b/trunk/drivers/ide/macide.c @@ -80,11 +80,6 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base, hw->chipset = ide_generic; } -static const struct ide_port_info macide_port_info = { - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, -}; - static const char *mac_ide_name[] = { "Quadra", "Powerbook", "Powerbook Baboon" }; @@ -127,7 +122,7 @@ static int __init macide_init(void) macide_setup_ports(&hw, base, irq, ack_intr); - return ide_host_add(&macide_port_info, hws, NULL); + return ide_host_add(NULL, hws, NULL); } module_init(macide_init); diff --git a/trunk/drivers/ide/ns87415.c b/trunk/drivers/ide/ns87415.c index 7b65fe5bf449..ea48a3ee8063 100644 --- a/trunk/drivers/ide/ns87415.c +++ b/trunk/drivers/ide/ns87415.c @@ -61,12 +61,12 @@ static u8 superio_dma_sff_read_status(ide_hwif_t *hwif) return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS); } -static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void superio_tf_read(ide_drive_t *drive, ide_task_t *task) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; - if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) { + if (task->tf_flags & IDE_TFLAG_IN_DATA) { u16 data = inw(io_ports->data_addr); tf->data = data & 0xff; @@ -76,31 +76,31 @@ static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) /* be sure we're looking at the low order bits */ outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) tf->feature = inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = superio_ide_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { + if (task->tf_flags & IDE_TFLAG_LBA48) { outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) tf->hob_feature = inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) tf->hob_nsect = inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) tf->hob_lbal = inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) tf->hob_lbam = inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) tf->hob_lbah = inb(io_ports->lbah_addr); } } @@ -216,11 +216,11 @@ static int ns87415_dma_end(ide_drive_t *drive) return (dma_stat & 7) != 4; } -static int ns87415_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static int ns87415_dma_setup(ide_drive_t *drive) { /* select DMA xfer */ ns87415_prepare_drive(drive, 1); - if (ide_dma_setup(drive, cmd) == 0) + if (!ide_dma_setup(drive)) return 0; /* DMA failed: select PIO xfer */ ns87415_prepare_drive(drive, 0); @@ -301,11 +301,11 @@ static const struct ide_port_ops ns87415_port_ops = { static const struct ide_dma_ops ns87415_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ns87415_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = ns87415_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = ide_dma_timeout, .dma_sff_read_status = superio_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/palm_bk3710.c b/trunk/drivers/ide/palm_bk3710.c index c7acca0b8733..f38aac78044c 100644 --- a/trunk/drivers/ide/palm_bk3710.c +++ b/trunk/drivers/ide/palm_bk3710.c @@ -347,7 +347,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev) struct clk *clk; struct resource *mem, *irq; void __iomem *base; - unsigned long rate, mem_size; + unsigned long rate; int i, rc; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; @@ -374,18 +374,13 @@ static int __init palm_bk3710_probe(struct platform_device *pdev) return -ENODEV; } - mem_size = mem->end - mem->start + 1; - if (request_mem_region(mem->start, mem_size, "palm_bk3710") == NULL) { + if (request_mem_region(mem->start, mem->end - mem->start + 1, + "palm_bk3710") == NULL) { printk(KERN_ERR "failed to request memory region\n"); return -EBUSY; } - base = ioremap(mem->start, mem_size); - if (!base) { - printk(KERN_ERR "failed to map IO memory\n"); - release_mem_region(mem->start, mem_size); - return -ENOMEM; - } + base = IO_ADDRESS(mem->start); /* Configure the Palm Chip controller */ palm_bk3710_chipinit(base); diff --git a/trunk/drivers/ide/pdc202xx_old.c b/trunk/drivers/ide/pdc202xx_old.c index f7536d1943f7..cba66ebce4e3 100644 --- a/trunk/drivers/ide/pdc202xx_old.c +++ b/trunk/drivers/ide/pdc202xx_old.c @@ -331,11 +331,11 @@ static const struct ide_port_ops pdc2026x_port_ops = { static const struct ide_dma_ops pdc20246_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = ide_dma_end, .dma_test_irq = pdc202xx_dma_test_irq, .dma_lost_irq = pdc202xx_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = pdc202xx_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; @@ -343,11 +343,11 @@ static const struct ide_dma_ops pdc20246_dma_ops = { static const struct ide_dma_ops pdc2026x_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = pdc202xx_dma_start, .dma_end = pdc202xx_dma_end, .dma_test_irq = pdc202xx_dma_test_irq, .dma_lost_irq = pdc202xx_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = pdc202xx_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/pmac.c b/trunk/drivers/ide/pmac.c index 2bfcfedaa076..74625e821a43 100644 --- a/trunk/drivers/ide/pmac.c +++ b/trunk/drivers/ide/pmac.c @@ -404,6 +404,7 @@ 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 int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq); static void pmac_ide_selectproc(ide_drive_t *drive); static void pmac_ide_kauai_selectproc(ide_drive_t *drive); @@ -1421,16 +1422,17 @@ int __init pmac_ide_probe(void) * pmac_ide_build_dmatable builds the DBDMA command list * for a transfer and sets the DBDMA channel to point to it. */ -static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) +static int +pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); struct dbdma_cmd *table; + int i, count = 0; volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; struct scatterlist *sg; - int wr = !!(cmd->tf_flags & IDE_TFLAG_WRITE); - int i = cmd->sg_nents, count = 0; + int wr = (rq_data_dir(rq) == WRITE); /* DMA table is already aligned */ table = (struct dbdma_cmd *) pmif->dma_table_cpu; @@ -1440,6 +1442,11 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) while (readl(&dma->status) & RUN) udelay(1); + hwif->sg_nents = i = ide_build_sglist(drive, rq); + + if (!i) + return 0; + /* Build DBDMA commands list */ sg = hwif->sg_table; while (i && sg_dma_len(sg)) { @@ -1502,22 +1509,23 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) * Prepare a DMA transfer. We build the DMA table, adjust the timings for * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion */ -static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static int +pmac_ide_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); + struct request *rq = hwif->rq; 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, rq)) { + ide_map_sg(drive, rq); return 1; } /* Apple adds 60ns to wrDataSetup on reads */ if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) { - writel(pmif->timings[unit] + (write ? 0 : 0x00800000UL), + writel(pmif->timings[unit] + (!rq_data_dir(rq) ? 0x00800000UL : 0), PMAC_IDE_REG(IDE_TIMING_CONFIG)); (void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG)); } @@ -1527,6 +1535,13 @@ static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) return 0; } +static void +pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command) +{ + /* issue cmd to drive */ + ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL); +} + /* * Kick the DMA controller into life after the DMA command has been issued * to the drive. @@ -1647,6 +1662,7 @@ pmac_ide_dma_lost_irq (ide_drive_t *drive) static const struct ide_dma_ops pmac_dma_ops = { .dma_host_set = pmac_ide_dma_host_set, .dma_setup = pmac_ide_dma_setup, + .dma_exec_cmd = pmac_ide_dma_exec_cmd, .dma_start = pmac_ide_dma_start, .dma_end = pmac_ide_dma_end, .dma_test_irq = pmac_ide_dma_test_irq, diff --git a/trunk/drivers/ide/q40ide.c b/trunk/drivers/ide/q40ide.c index 2a43a2f49633..9f9c0b3cc3a3 100644 --- a/trunk/drivers/ide/q40ide.c +++ b/trunk/drivers/ide/q40ide.c @@ -72,26 +72,26 @@ static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base, hw->chipset = ide_generic; } -static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void q40ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; - if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) + if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) return insw(data_addr, buf, (len + 1) / 2); - raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2); + insw_swapw(data_addr, buf, (len + 1) / 2); } -static void q40ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void q40ide_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; - if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) + if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) return outsw(data_addr, buf, (len + 1) / 2); - raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2); + outsw_swapw(data_addr, buf, (len + 1) / 2); } /* Q40 has a byte-swapped IDE interface */ @@ -111,8 +111,7 @@ static const struct ide_tp_ops q40ide_tp_ops = { static const struct ide_port_info q40ide_port_info = { .tp_ops = &q40ide_tp_ops, - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, + .host_flags = IDE_HFLAG_NO_DMA, }; /* diff --git a/trunk/drivers/ide/sc1200.c b/trunk/drivers/ide/sc1200.c index 1c3a82914999..dbdd2985a0d8 100644 --- a/trunk/drivers/ide/sc1200.c +++ b/trunk/drivers/ide/sc1200.c @@ -286,11 +286,11 @@ static const struct ide_port_ops sc1200_port_ops = { static const struct ide_dma_ops sc1200_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = sc1200_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/scc_pata.c b/trunk/drivers/ide/scc_pata.c index 0cc137cfe76d..8d2314b6327c 100644 --- a/trunk/drivers/ide/scc_pata.c +++ b/trunk/drivers/ide/scc_pata.c @@ -303,9 +303,8 @@ static void scc_dma_host_set(ide_drive_t *drive, int on) } /** - * scc_dma_setup - begin a DMA phase + * scc_ide_dma_setup - begin a DMA phase * @drive: target device - * @cmd: command * * Build an IDE DMA PRD (IDE speak for scatter gather table) * and then set up the DMA transfer registers. @@ -314,15 +313,21 @@ static void scc_dma_host_set(ide_drive_t *drive, int on) * is returned. */ -static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static int scc_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR; + struct request *rq = hwif->rq; + unsigned int reading; u8 dma_stat; + if (rq_data_dir(rq)) + reading = 0; + else + reading = 1 << 3; + /* fall back to pio! */ - if (ide_build_dmatable(drive, cmd) == 0) { - ide_map_sg(drive, cmd); + if (!ide_build_dmatable(drive, rq)) { + ide_map_sg(drive, rq); return 1; } @@ -330,7 +335,7 @@ static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma); /* specify r/w */ - out_be32((void __iomem *)hwif->dma_base, rw); + out_be32((void __iomem *)hwif->dma_base, reading); /* read DMA status for INTR & ERROR flags */ dma_stat = scc_dma_sff_read_status(hwif); @@ -661,52 +666,52 @@ static int __devinit init_setup_scc(struct pci_dev *dev, return rc; } -static void scc_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void scc_tf_load(ide_drive_t *drive, ide_task_t *task) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; - u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) + if (task->tf_flags & IDE_TFLAG_OUT_DATA) out_be32((void *)io_ports->data_addr, (tf->hob_data << 8) | tf->data); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) + if (task->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) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) scc_ide_outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) scc_ide_outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) scc_ide_outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) scc_ide_outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) scc_ide_outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) scc_ide_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } -static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void scc_tf_read(ide_drive_t *drive, ide_task_t *task) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; - if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) { + if (task->tf_flags & IDE_TFLAG_IN_DATA) { u16 data = (u16)in_be32((void *)io_ports->data_addr); tf->data = data & 0xff; @@ -716,36 +721,36 @@ static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) /* be sure we're looking at the low order bits */ scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) tf->feature = scc_ide_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = scc_ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = scc_ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = scc_ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = scc_ide_inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = scc_ide_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { + if (task->tf_flags & IDE_TFLAG_LBA48) { scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + if (task->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_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr); } } -static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void scc_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; @@ -761,7 +766,7 @@ static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd, scc_ide_insw(data_addr, buf, len / 2); } -static void scc_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void scc_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; @@ -868,26 +873,30 @@ static const struct ide_port_ops scc_port_ops = { static const struct ide_dma_ops scc_dma_ops = { .dma_host_set = scc_dma_host_set, .dma_setup = scc_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = scc_dma_start, .dma_end = scc_dma_end, .dma_test_irq = scc_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, .dma_timeout = ide_dma_timeout, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_sff_read_status = scc_dma_sff_read_status, }; -static const struct ide_port_info scc_chipset __devinitdata = { - .name = "sccIDE", - .init_iops = init_iops_scc, - .init_dma = scc_init_dma, - .init_hwif = init_hwif_scc, - .tp_ops = &scc_tp_ops, - .port_ops = &scc_port_ops, - .dma_ops = &scc_dma_ops, - .host_flags = IDE_HFLAG_SINGLE, - .irq_flags = IRQF_SHARED, - .pio_mask = ATA_PIO4, +#define DECLARE_SCC_DEV(name_str) \ + { \ + .name = name_str, \ + .init_iops = init_iops_scc, \ + .init_dma = scc_init_dma, \ + .init_hwif = init_hwif_scc, \ + .tp_ops = &scc_tp_ops, \ + .port_ops = &scc_port_ops, \ + .dma_ops = &scc_dma_ops, \ + .host_flags = IDE_HFLAG_SINGLE, \ + .pio_mask = ATA_PIO4, \ + } + +static const struct ide_port_info scc_chipsets[] __devinitdata = { + /* 0 */ DECLARE_SCC_DEV("sccIDE"), }; /** @@ -901,7 +910,7 @@ static const struct ide_port_info scc_chipset __devinitdata = { static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - return init_setup_scc(dev, &scc_chipset); + return init_setup_scc(dev, &scc_chipsets[id->driver_data]); } /** diff --git a/trunk/drivers/ide/setup-pci.c b/trunk/drivers/ide/setup-pci.c index a19dbccd7617..24bc884826fc 100644 --- a/trunk/drivers/ide/setup-pci.c +++ b/trunk/drivers/ide/setup-pci.c @@ -558,8 +558,6 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d, host->host_priv = priv; - host->irq_flags = IRQF_SHARED; - pci_set_drvdata(dev, host); ret = do_ide_setup_pci_device(dev, d, 1); @@ -608,8 +606,6 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, host->host_priv = priv; - host->irq_flags = IRQF_SHARED; - pci_set_drvdata(pdev[0], host); pci_set_drvdata(pdev[1], host); diff --git a/trunk/drivers/ide/sgiioc4.c b/trunk/drivers/ide/sgiioc4.c index b12de8346c73..fdb9d7037694 100644 --- a/trunk/drivers/ide/sgiioc4.c +++ b/trunk/drivers/ide/sgiioc4.c @@ -424,13 +424,20 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) /* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */ /* --------------------------------------------------------------------- */ /* Creates the scatter gather list, DMA Table */ -static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) +static unsigned int +sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir) { ide_hwif_t *hwif = drive->hwif; unsigned int *table = hwif->dmatable_cpu; - unsigned int count = 0, i = cmd->sg_nents; - struct scatterlist *sg = hwif->sg_table; + unsigned int count = 0, i = 1; + struct scatterlist *sg; + hwif->sg_nents = i = ide_build_sglist(drive, rq); + + if (!i) + return 0; /* sglist of length Zero */ + + sg = hwif->sg_table; while (i && sg_dma_len(sg)) { dma_addr_t cur_addr; int cur_len; @@ -483,18 +490,24 @@ static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) return 0; /* revert to PIO for this request */ } -static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static int sgiioc4_dma_setup(ide_drive_t *drive) { + struct request *rq = drive->hwif->rq; + unsigned int count = 0; int ddir; - u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE); - if (sgiioc4_build_dmatable(drive, cmd) == 0) { + if (rq_data_dir(rq)) + ddir = PCI_DMA_TODEVICE; + else + ddir = PCI_DMA_FROMDEVICE; + + if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) { /* try PIO instead of DMA */ - ide_map_sg(drive, cmd); + ide_map_sg(drive, rq); return 1; } - if (write) + if (rq_data_dir(rq)) /* Writes TO the IOC4 FROM Main Memory */ ddir = IOC4_DMA_READ; else @@ -544,7 +557,6 @@ static const struct ide_port_info sgiioc4_port_info __devinitconst = { .port_ops = &sgiioc4_port_ops, .dma_ops = &sgiioc4_dma_ops, .host_flags = IDE_HFLAG_MMIO, - .irq_flags = IRQF_SHARED, .mwdma_mask = ATA_MWDMA2_ONLY, }; diff --git a/trunk/drivers/ide/siimage.c b/trunk/drivers/ide/siimage.c index 075cb1243b2a..1811ae9cd843 100644 --- a/trunk/drivers/ide/siimage.c +++ b/trunk/drivers/ide/siimage.c @@ -711,10 +711,10 @@ static const struct ide_port_ops sil_sata_port_ops = { static const struct ide_dma_ops sil_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = ide_dma_end, .dma_test_irq = siimage_dma_test_irq, - .dma_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, diff --git a/trunk/drivers/ide/sl82c105.c b/trunk/drivers/ide/sl82c105.c index d25137b04e7a..dba213c51baa 100644 --- a/trunk/drivers/ide/sl82c105.c +++ b/trunk/drivers/ide/sl82c105.c @@ -293,11 +293,11 @@ static const struct ide_port_ops sl82c105_port_ops = { static const struct ide_dma_ops sl82c105_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = sl82c105_dma_start, .dma_end = sl82c105_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = sl82c105_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = sl82c105_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/tc86c001.c b/trunk/drivers/ide/tc86c001.c index 427d4b3c2c63..84109f5a1632 100644 --- a/trunk/drivers/ide/tc86c001.c +++ b/trunk/drivers/ide/tc86c001.c @@ -182,11 +182,11 @@ static const struct ide_port_ops tc86c001_port_ops = { static const struct ide_dma_ops tc86c001_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = tc86c001_dma_start, .dma_end = ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/trm290.c b/trunk/drivers/ide/trm290.c index ed1496845a93..1c09e549c423 100644 --- a/trunk/drivers/ide/trm290.c +++ b/trunk/drivers/ide/trm290.c @@ -176,12 +176,18 @@ static void trm290_selectproc (ide_drive_t *drive) trm290_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA)); } -static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command) +{ + ide_execute_command(drive, command, &ide_dma_intr, WAIT_CMD, NULL); +} + +static int trm290_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->rq; unsigned int count, rw; - if (cmd->tf_flags & IDE_TFLAG_WRITE) { + if (rq_data_dir(rq)) { #ifdef TRM290_NO_DMA_WRITES /* always use PIO for writes */ trm290_prepare_drive(drive, 0); /* select PIO xfer */ @@ -191,9 +197,7 @@ static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) } else rw = 2; - count = ide_build_dmatable(drive, cmd); - if (count == 0) { - ide_map_sg(drive, cmd); + if (!(count = ide_build_dmatable(drive, rq))) { /* try PIO instead of DMA */ trm290_prepare_drive(drive, 0); /* select PIO xfer */ return 1; @@ -310,6 +314,7 @@ static const struct ide_port_ops trm290_port_ops = { static struct ide_dma_ops trm290_dma_ops = { .dma_host_set = trm290_dma_host_set, .dma_setup = trm290_dma_setup, + .dma_exec_cmd = trm290_dma_exec_cmd, .dma_start = trm290_dma_start, .dma_end = trm290_dma_end, .dma_test_irq = trm290_dma_test_irq, diff --git a/trunk/drivers/ide/tx4938ide.c b/trunk/drivers/ide/tx4938ide.c index 657a61890b1c..d9095345f7ca 100644 --- a/trunk/drivers/ide/tx4938ide.c +++ b/trunk/drivers/ide/tx4938ide.c @@ -15,8 +15,6 @@ #include #include #include - -#include #include static void tx4938ide_tune_ebusc(unsigned int ebus_ch, @@ -82,57 +80,57 @@ static void tx4938ide_outb(u8 value, unsigned long port) __raw_writeb(value, (void __iomem *)port); } -static void tx4938ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void tx4938ide_tf_load(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; - u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) { + if (task->tf_flags & IDE_TFLAG_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) + if (task->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) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) tx4938ide_outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) tx4938ide_outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) tx4938ide_outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) tx4938ide_outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) tx4938ide_outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) tx4938ide_outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) tx4938ide_outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) tx4938ide_outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) tx4938ide_outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) tx4938ide_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } -static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void tx4938ide_tf_read(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; - if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) { + if (task->tf_flags & IDE_TFLAG_IN_DATA) { u16 data; /* no endian swap */ @@ -144,37 +142,37 @@ static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) /* be sure we're looking at the low order bits */ tx4938ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) tf->feature = tx4938ide_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = tx4938ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = tx4938ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = tx4938ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = tx4938ide_inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = tx4938ide_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { + if (task->tf_flags & IDE_TFLAG_LBA48) { tx4938ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) tf->hob_feature = tx4938ide_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr); } } -static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd, +static void tx4938ide_input_data_swap(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long port = drive->hwif->io_ports.data_addr; @@ -186,7 +184,7 @@ static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd, __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); } -static void tx4938ide_output_data_swap(ide_drive_t *drive, struct ide_cmd *cmd, +static void tx4938ide_output_data_swap(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long port = drive->hwif->io_ports.data_addr; diff --git a/trunk/drivers/ide/tx4939ide.c b/trunk/drivers/ide/tx4939ide.c index e0e0a803dde3..40b0812a045c 100644 --- a/trunk/drivers/ide/tx4939ide.c +++ b/trunk/drivers/ide/tx4939ide.c @@ -18,8 +18,6 @@ #include #include -#include - #define MODNAME "tx4939ide" /* ATA Shadow Registers (8-bit except for Data which is 16-bit) */ @@ -232,7 +230,7 @@ static u8 tx4939ide_clear_dma_status(void __iomem *base) #ifdef __BIG_ENDIAN /* custom ide_build_dmatable to handle swapped layout */ -static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) +static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; u32 *table = (u32 *)hwif->dmatable_cpu; @@ -240,7 +238,11 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) int i; struct scatterlist *sg; - for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) { + hwif->sg_nents = ide_build_sglist(drive, rq); + if (hwif->sg_nents == 0) + return 0; + + for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) { u32 cur_addr, cur_len, bcount; cur_addr = sg_dma_address(sg); @@ -287,15 +289,23 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) #define tx4939ide_build_dmatable ide_build_dmatable #endif -static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static int tx4939ide_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; void __iomem *base = TX4939IDE_BASE(hwif); - u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR; + struct request *rq = hwif->rq; + u8 reading; + int nent; + + if (rq_data_dir(rq)) + reading = 0; + else + reading = ATA_DMA_WR; /* fall back to PIO! */ - if (tx4939ide_build_dmatable(drive, cmd) == 0) { - ide_map_sg(drive, cmd); + nent = tx4939ide_build_dmatable(drive, rq); + if (!nent) { + ide_map_sg(drive, rq); return 1; } @@ -303,7 +313,7 @@ static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr); /* specify r/w */ - tx4939ide_writeb(rw, base, TX4939IDE_DMA_Cmd); + tx4939ide_writeb(reading, base, TX4939IDE_DMA_Cmd); /* clear INTR & ERROR flags */ tx4939ide_clear_dma_status(base); @@ -312,9 +322,7 @@ static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ? TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1); - - tx4939ide_writew(cmd->rq->nr_sectors, base, TX4939IDE_Sec_Cnt); - + tx4939ide_writew(rq->nr_sectors, base, TX4939IDE_Sec_Cnt); return 0; } @@ -429,7 +437,7 @@ static int tx4939ide_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d) return ide_allocate_dma_engine(hwif); } -static void tx4939ide_tf_load_fixup(ide_drive_t *drive) +static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; void __iomem *base = TX4939IDE_BASE(hwif); @@ -457,59 +465,59 @@ static void tx4939ide_outb(u8 value, unsigned long port) __raw_writeb(value, (void __iomem *)port); } -static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; - u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) { + if (task->tf_flags & IDE_TFLAG_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) + if (task->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) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) tx4939ide_outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) tx4939ide_outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) tx4939ide_outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) tx4939ide_outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) tx4939ide_outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) tx4939ide_outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) tx4939ide_outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) tx4939ide_outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) tx4939ide_outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) { + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) { tx4939ide_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); - tx4939ide_tf_load_fixup(drive); + tx4939ide_tf_load_fixup(drive, task); } } -static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void tx4939ide_tf_read(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; - if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) { + if (task->tf_flags & IDE_TFLAG_IN_DATA) { u16 data; /* no endian swap */ @@ -521,32 +529,32 @@ static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) /* be sure we're looking at the low order bits */ tx4939ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) tf->feature = tx4939ide_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = tx4939ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = tx4939ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = tx4939ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = tx4939ide_inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = tx4939ide_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { + if (task->tf_flags & IDE_TFLAG_LBA48) { tx4939ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) tf->hob_feature = tx4939ide_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr); } } @@ -593,12 +601,11 @@ static const struct ide_tp_ops tx4939ide_tp_ops = { #else /* __LITTLE_ENDIAN */ -static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task) { - ide_tf_load(drive, cmd); - - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) - tx4939ide_tf_load_fixup(drive); + ide_tf_load(drive, task); + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) + tx4939ide_tf_load_fixup(drive, task); } static const struct ide_tp_ops tx4939ide_tp_ops = { @@ -627,11 +634,11 @@ static const struct ide_port_ops tx4939ide_port_ops = { static const struct ide_dma_ops tx4939ide_dma_ops = { .dma_host_set = tx4939ide_dma_host_set, .dma_setup = tx4939ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = tx4939ide_dma_end, .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, }; diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index d9fdb7cec538..821d10f719bd 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -1465,7 +1465,7 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin) case SEEK_END: retval = fuse_update_attributes(inode, NULL, file, NULL); if (retval) - return retval; + goto exit; offset += i_size_read(inode); break; case SEEK_CUR: @@ -1479,6 +1479,7 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin) } retval = offset; } +exit: mutex_unlock(&inode->i_mutex); return retval; } diff --git a/trunk/fs/jfs/Kconfig b/trunk/fs/jfs/Kconfig index 57cef19951db..9ff619a6f9cc 100644 --- a/trunk/fs/jfs/Kconfig +++ b/trunk/fs/jfs/Kconfig @@ -1,7 +1,6 @@ config JFS_FS tristate "JFS filesystem support" select NLS - select CRC32 help This is a port of IBM's Journaled Filesystem . More information is available in the file . diff --git a/trunk/fs/jfs/jfs_extent.c b/trunk/fs/jfs/jfs_extent.c index bbbd5f202e37..169802ea07f9 100644 --- a/trunk/fs/jfs/jfs_extent.c +++ b/trunk/fs/jfs/jfs_extent.c @@ -362,12 +362,11 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) int extHint(struct inode *ip, s64 offset, xad_t * xp) { struct super_block *sb = ip->i_sb; - int nbperpage = JFS_SBI(sb)->nbperpage; + struct xadlist xadl; + struct lxdlist lxdl; + lxd_t lxd; s64 prev; - int rc = 0; - s64 xaddr; - int xlen; - int xflag; + int rc, nbperpage = JFS_SBI(sb)->nbperpage; /* init the hint as "no hint provided" */ XADaddress(xp, 0); @@ -377,30 +376,46 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp) */ prev = ((offset & ~POFFSET) >> JFS_SBI(sb)->l2bsize) - nbperpage; - /* if the offset is in the first page of the file, no hint provided. + /* if the offsets in the first page of the file, + * no hint provided. */ if (prev < 0) - goto out; + return (0); - rc = xtLookup(ip, prev, nbperpage, &xflag, &xaddr, &xlen, 0); + /* prepare to lookup the previous page's extent info */ + lxdl.maxnlxd = 1; + lxdl.nlxd = 1; + lxdl.lxd = &lxd; + LXDoffset(&lxd, prev) + LXDlength(&lxd, nbperpage); - if ((rc == 0) && xlen) { - if (xlen != nbperpage) { - jfs_error(ip->i_sb, "extHint: corrupt xtree"); - rc = -EIO; - } - XADaddress(xp, xaddr); - XADlength(xp, xlen); - /* - * only preserve the abnr flag within the xad flags - * of the returned hint. - */ - xp->flag = xflag & XAD_NOTRECORDED; - } else - rc = 0; + xadl.maxnxad = 1; + xadl.nxad = 0; + xadl.xad = xp; -out: - return (rc); + /* perform the lookup */ + if ((rc = xtLookupList(ip, &lxdl, &xadl, 0))) + return (rc); + + /* check if no extent exists for the previous page. + * this is possible for sparse files. + */ + if (xadl.nxad == 0) { +// assert(ISSPARSE(ip)); + return (0); + } + + /* only preserve the abnr flag within the xad flags + * of the returned hint. + */ + xp->flag &= XAD_NOTRECORDED; + + if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) { + jfs_error(ip->i_sb, "extHint: corrupt xtree"); + return -EIO; + } + + return (0); } diff --git a/trunk/fs/jfs/jfs_imap.c b/trunk/fs/jfs/jfs_imap.c index 346057218edc..0f94381ca6d0 100644 --- a/trunk/fs/jfs/jfs_imap.c +++ b/trunk/fs/jfs/jfs_imap.c @@ -56,6 +56,12 @@ #include "jfs_superblock.h" #include "jfs_debug.h" +/* + * __mark_inode_dirty expects inodes to be hashed. Since we don't want + * special inodes in the fileset inode space, we make them appear hashed, + * but do not put on any lists. + */ + /* * imap locks */ @@ -491,9 +497,7 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) release_metapage(mp); /* - * __mark_inode_dirty expects inodes to be hashed. Since we don't - * want special inodes in the fileset inode space, we make them - * appear hashed, but do not put on any lists. hlist_del() + * that will look hashed, but won't be on any list; hlist_del() * will work fine and require no locking. */ ip->i_hash.pprev = &ip->i_hash.next; diff --git a/trunk/fs/jfs/jfs_metapage.c b/trunk/fs/jfs/jfs_metapage.c index 07b6c5dfb4b6..c350057087dd 100644 --- a/trunk/fs/jfs/jfs_metapage.c +++ b/trunk/fs/jfs/jfs_metapage.c @@ -369,7 +369,6 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) unsigned long bio_bytes = 0; unsigned long bio_offset = 0; int offset; - int bad_blocks = 0; page_start = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); @@ -395,7 +394,6 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) } clear_bit(META_dirty, &mp->flag); - set_bit(META_io, &mp->flag); block_offset = offset >> inode->i_blkbits; lblock = page_start + block_offset; if (bio) { @@ -404,6 +402,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) len = min(xlen, blocks_per_mp); xlen -= len; bio_bytes += len << inode->i_blkbits; + set_bit(META_io, &mp->flag); continue; } /* Not contiguous */ @@ -425,14 +424,12 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) xlen = (PAGE_CACHE_SIZE - offset) >> inode->i_blkbits; pblock = metapage_get_blocks(inode, lblock, &xlen); if (!pblock) { + /* Need better error handling */ printk(KERN_ERR "JFS: metapage_get_blocks failed\n"); - /* - * We already called inc_io(), but can't cancel it - * with dec_io() until we're done with the page - */ - bad_blocks++; + dec_io(page, last_write_complete); continue; } + set_bit(META_io, &mp->flag); len = min(xlen, (int)JFS_SBI(inode->i_sb)->nbperpage); bio = bio_alloc(GFP_NOFS, 1); @@ -462,9 +459,6 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) unlock_page(page); - if (bad_blocks) - goto err_out; - if (nr_underway == 0) end_page_writeback(page); @@ -480,9 +474,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) bio_put(bio); unlock_page(page); dec_io(page, last_write_complete); -err_out: - while (bad_blocks--) - dec_io(page, last_write_complete); + return -EIO; } diff --git a/trunk/fs/jfs/jfs_types.h b/trunk/fs/jfs/jfs_types.h index 43ea3713c083..649f9817accd 100644 --- a/trunk/fs/jfs/jfs_types.h +++ b/trunk/fs/jfs/jfs_types.h @@ -57,6 +57,35 @@ struct timestruc_t { #define HIGHORDER 0x80000000u /* high order bit on */ #define ONES 0xffffffffu /* all bit on */ +/* + * logical xd (lxd) + */ +typedef struct { + unsigned len:24; + unsigned off1:8; + u32 off2; +} lxd_t; + +/* lxd_t field construction */ +#define LXDlength(lxd, length32) ( (lxd)->len = length32 ) +#define LXDoffset(lxd, offset64)\ +{\ + (lxd)->off1 = ((s64)offset64) >> 32;\ + (lxd)->off2 = (offset64) & 0xffffffff;\ +} + +/* lxd_t field extraction */ +#define lengthLXD(lxd) ( (lxd)->len ) +#define offsetLXD(lxd)\ + ( ((s64)((lxd)->off1)) << 32 | (lxd)->off2 ) + +/* lxd list */ +struct lxdlist { + s16 maxnlxd; + s16 nlxd; + lxd_t *lxd; +}; + /* * physical xd (pxd) */ diff --git a/trunk/fs/jfs/jfs_xtree.c b/trunk/fs/jfs/jfs_xtree.c index d654a6458648..a27e26c90568 100644 --- a/trunk/fs/jfs/jfs_xtree.c +++ b/trunk/fs/jfs/jfs_xtree.c @@ -164,8 +164,11 @@ int xtLookup(struct inode *ip, s64 lstart, /* is lookup offset beyond eof ? */ size = ((u64) ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >> JFS_SBI(ip->i_sb)->l2bsize; - if (lstart >= size) + if (lstart >= size) { + jfs_err("xtLookup: lstart (0x%lx) >= size (0x%lx)", + (ulong) lstart, (ulong) size); return 0; + } } /* @@ -217,6 +220,264 @@ int xtLookup(struct inode *ip, s64 lstart, return rc; } + +/* + * xtLookupList() + * + * function: map a single logical extent into a list of physical extent; + * + * parameter: + * struct inode *ip, + * struct lxdlist *lxdlist, lxd list (in) + * struct xadlist *xadlist, xad list (in/out) + * int flag) + * + * coverage of lxd by xad under assumption of + * . lxd's are ordered and disjoint. + * . xad's are ordered and disjoint. + * + * return: + * 0: success + * + * note: a page being written (even a single byte) is backed fully, + * except the last page which is only backed with blocks + * required to cover the last byte; + * the extent backing a page is fully contained within an xad; + */ +int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, + struct xadlist * xadlist, int flag) +{ + int rc = 0; + struct btstack btstack; + int cmp; + s64 bn; + struct metapage *mp; + xtpage_t *p; + int index; + lxd_t *lxd; + xad_t *xad, *pxd; + s64 size, lstart, lend, xstart, xend, pstart; + s64 llen, xlen, plen; + s64 xaddr, paddr; + int nlxd, npxd, maxnpxd; + + npxd = xadlist->nxad = 0; + maxnpxd = xadlist->maxnxad; + pxd = xadlist->xad; + + nlxd = lxdlist->nlxd; + lxd = lxdlist->lxd; + + lstart = offsetLXD(lxd); + llen = lengthLXD(lxd); + lend = lstart + llen; + + size = (ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >> + JFS_SBI(ip->i_sb)->l2bsize; + + /* + * search for the xad entry covering the logical extent + */ + search: + if (lstart >= size) + return 0; + + if ((rc = xtSearch(ip, lstart, NULL, &cmp, &btstack, 0))) + return rc; + + /* + * compute the physical extent covering logical extent + * + * N.B. search may have failed (e.g., hole in sparse file), + * and returned the index of the next entry. + */ +//map: + /* retrieve search result */ + XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + + /* is xad on the next sibling page ? */ + if (index == le16_to_cpu(p->header.nextindex)) { + if (p->header.flag & BT_ROOT) + goto mapend; + + if ((bn = le64_to_cpu(p->header.next)) == 0) + goto mapend; + + XT_PUTPAGE(mp); + + /* get next sibling page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + index = XTENTRYSTART; + } + + xad = &p->xad[index]; + + /* + * is lxd covered by xad ? + */ + compare: + xstart = offsetXAD(xad); + xlen = lengthXAD(xad); + xend = xstart + xlen; + xaddr = addressXAD(xad); + + compare1: + if (xstart < lstart) + goto compare2; + + /* (lstart <= xstart) */ + + /* lxd is NOT covered by xad */ + if (lend <= xstart) { + /* + * get next lxd + */ + if (--nlxd == 0) + goto mapend; + lxd++; + + lstart = offsetLXD(lxd); + llen = lengthLXD(lxd); + lend = lstart + llen; + if (lstart >= size) + goto mapend; + + /* compare with the current xad */ + goto compare1; + } + /* lxd is covered by xad */ + else { /* (xstart < lend) */ + + /* initialize new pxd */ + pstart = xstart; + plen = min(lend - xstart, xlen); + paddr = xaddr; + + goto cover; + } + + /* (xstart < lstart) */ + compare2: + /* lxd is covered by xad */ + if (lstart < xend) { + /* initialize new pxd */ + pstart = lstart; + plen = min(xend - lstart, llen); + paddr = xaddr + (lstart - xstart); + + goto cover; + } + /* lxd is NOT covered by xad */ + else { /* (xend <= lstart) */ + + /* + * get next xad + * + * linear search next xad covering lxd on + * the current xad page, and then tree search + */ + if (index == le16_to_cpu(p->header.nextindex) - 1) { + if (p->header.flag & BT_ROOT) + goto mapend; + + XT_PUTPAGE(mp); + goto search; + } else { + index++; + xad++; + + /* compare with new xad */ + goto compare; + } + } + + /* + * lxd is covered by xad and a new pxd has been initialized + * (lstart <= xstart < lend) or (xstart < lstart < xend) + */ + cover: + /* finalize pxd corresponding to current xad */ + XT_PUTENTRY(pxd, xad->flag, pstart, plen, paddr); + + if (++npxd >= maxnpxd) + goto mapend; + pxd++; + + /* + * lxd is fully covered by xad + */ + if (lend <= xend) { + /* + * get next lxd + */ + if (--nlxd == 0) + goto mapend; + lxd++; + + lstart = offsetLXD(lxd); + llen = lengthLXD(lxd); + lend = lstart + llen; + if (lstart >= size) + goto mapend; + + /* + * test for old xad covering new lxd + * (old xstart < new lstart) + */ + goto compare2; + } + /* + * lxd is partially covered by xad + */ + else { /* (xend < lend) */ + + /* + * get next xad + * + * linear search next xad covering lxd on + * the current xad page, and then next xad page search + */ + if (index == le16_to_cpu(p->header.nextindex) - 1) { + if (p->header.flag & BT_ROOT) + goto mapend; + + if ((bn = le64_to_cpu(p->header.next)) == 0) + goto mapend; + + XT_PUTPAGE(mp); + + /* get next sibling page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + index = XTENTRYSTART; + xad = &p->xad[index]; + } else { + index++; + xad++; + } + + /* + * test for new xad covering old lxd + * (old lstart < new xstart) + */ + goto compare; + } + + mapend: + xadlist->nxad = npxd; + +//out: + XT_PUTPAGE(mp); + + return rc; +} + + /* * xtSearch() * diff --git a/trunk/fs/jfs/jfs_xtree.h b/trunk/fs/jfs/jfs_xtree.h index 08c0c749b986..70815c8a3d6a 100644 --- a/trunk/fs/jfs/jfs_xtree.h +++ b/trunk/fs/jfs/jfs_xtree.h @@ -110,6 +110,8 @@ typedef union { */ extern int xtLookup(struct inode *ip, s64 lstart, s64 llen, int *pflag, s64 * paddr, int *plen, int flag); +extern int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, + struct xadlist * xadlist, int flag); extern void xtInitRoot(tid_t tid, struct inode *ip); extern int xtInsert(tid_t tid, struct inode *ip, int xflag, s64 xoff, int xlen, s64 * xaddrp, int flag); diff --git a/trunk/fs/jfs/super.c b/trunk/fs/jfs/super.c index 6f21adf9479a..b37d1f78b854 100644 --- a/trunk/fs/jfs/super.c +++ b/trunk/fs/jfs/super.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -169,9 +168,6 @@ static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_files = maxinodes; buf->f_ffree = maxinodes - (atomic_read(&imap->im_numinos) - atomic_read(&imap->im_numfree)); - buf->f_fsid.val[0] = (u32)crc32_le(0, sbi->uuid, sizeof(sbi->uuid)/2); - buf->f_fsid.val[1] = (u32)crc32_le(0, sbi->uuid + sizeof(sbi->uuid)/2, - sizeof(sbi->uuid)/2); buf->f_namelen = JFS_NAME_MAX; return 0; diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index d5d832271f44..854eba8b2ba3 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -40,13 +40,6 @@ #define ERROR_RESET 3 /* Reset controller every 4th retry */ #define ERROR_RECAL 1 /* Recalibrate every 2nd retry */ -/* Error codes returned in rq->errors to the higher part of the driver. */ -enum { - IDE_DRV_ERROR_GENERAL = 101, - IDE_DRV_ERROR_FILEMARK = 102, - IDE_DRV_ERROR_EOD = 103, -}; - /* * Definitions for accessing IDE controller registers */ @@ -200,8 +193,26 @@ static inline void ide_std_init_ports(hw_regs_t *hw, hw->io_ports.ctl_addr = ctl_addr; } +#if defined(CONFIG_ARM) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \ + defined(CONFIG_PARISC) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) +#include +#else +#include +#endif + #define MAX_HWIFS 10 +/* Currently only m68k, apus and m8xx need it */ +#ifndef IDE_ARCH_ACK_INTR +# define ide_ack_intr(hwif) (1) +#endif + +/* Currently only Atari needs it */ +#ifndef IDE_ARCH_LOCK +# define ide_release_lock() do {} while (0) +# define ide_get_lock(hdlr, data) do {} while (0) +#endif /* IDE_ARCH_LOCK */ + /* * Now for the data we need to maintain per-drive: ide_drive_t */ @@ -241,52 +252,56 @@ typedef enum { enum { IDE_TFLAG_LBA48 = (1 << 0), - IDE_TFLAG_OUT_HOB_FEATURE = (1 << 1), - IDE_TFLAG_OUT_HOB_NSECT = (1 << 2), - IDE_TFLAG_OUT_HOB_LBAL = (1 << 3), - IDE_TFLAG_OUT_HOB_LBAM = (1 << 4), - IDE_TFLAG_OUT_HOB_LBAH = (1 << 5), + IDE_TFLAG_FLAGGED = (1 << 2), + IDE_TFLAG_OUT_DATA = (1 << 3), + IDE_TFLAG_OUT_HOB_FEATURE = (1 << 4), + IDE_TFLAG_OUT_HOB_NSECT = (1 << 5), + IDE_TFLAG_OUT_HOB_LBAL = (1 << 6), + IDE_TFLAG_OUT_HOB_LBAM = (1 << 7), + IDE_TFLAG_OUT_HOB_LBAH = (1 << 8), IDE_TFLAG_OUT_HOB = IDE_TFLAG_OUT_HOB_FEATURE | IDE_TFLAG_OUT_HOB_NSECT | IDE_TFLAG_OUT_HOB_LBAL | IDE_TFLAG_OUT_HOB_LBAM | IDE_TFLAG_OUT_HOB_LBAH, - IDE_TFLAG_OUT_FEATURE = (1 << 6), - IDE_TFLAG_OUT_NSECT = (1 << 7), - IDE_TFLAG_OUT_LBAL = (1 << 8), - IDE_TFLAG_OUT_LBAM = (1 << 9), - IDE_TFLAG_OUT_LBAH = (1 << 10), + IDE_TFLAG_OUT_FEATURE = (1 << 9), + IDE_TFLAG_OUT_NSECT = (1 << 10), + IDE_TFLAG_OUT_LBAL = (1 << 11), + IDE_TFLAG_OUT_LBAM = (1 << 12), + IDE_TFLAG_OUT_LBAH = (1 << 13), IDE_TFLAG_OUT_TF = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL | IDE_TFLAG_OUT_LBAM | IDE_TFLAG_OUT_LBAH, - IDE_TFLAG_OUT_DEVICE = (1 << 11), - 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_NSECT = (1 << 16), - IDE_TFLAG_IN_HOB_LBAL = (1 << 17), - IDE_TFLAG_IN_HOB_LBAM = (1 << 18), - IDE_TFLAG_IN_HOB_LBAH = (1 << 19), + IDE_TFLAG_OUT_DEVICE = (1 << 14), + IDE_TFLAG_WRITE = (1 << 15), + IDE_TFLAG_FLAGGED_SET_IN_FLAGS = (1 << 16), + IDE_TFLAG_IN_DATA = (1 << 17), + IDE_TFLAG_CUSTOM_HANDLER = (1 << 18), + IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 19), + IDE_TFLAG_IN_HOB_FEATURE = (1 << 20), + IDE_TFLAG_IN_HOB_NSECT = (1 << 21), + IDE_TFLAG_IN_HOB_LBAL = (1 << 22), + IDE_TFLAG_IN_HOB_LBAM = (1 << 23), + IDE_TFLAG_IN_HOB_LBAH = (1 << 24), 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_NSECT | IDE_TFLAG_IN_HOB_LBA, - IDE_TFLAG_IN_FEATURE = (1 << 20), - IDE_TFLAG_IN_NSECT = (1 << 21), - IDE_TFLAG_IN_LBAL = (1 << 22), - IDE_TFLAG_IN_LBAM = (1 << 23), - IDE_TFLAG_IN_LBAH = (1 << 24), + IDE_TFLAG_IN_FEATURE = (1 << 1), + IDE_TFLAG_IN_NSECT = (1 << 25), + IDE_TFLAG_IN_LBAL = (1 << 26), + IDE_TFLAG_IN_LBAM = (1 << 27), + IDE_TFLAG_IN_LBAH = (1 << 28), IDE_TFLAG_IN_LBA = IDE_TFLAG_IN_LBAL | IDE_TFLAG_IN_LBAM | IDE_TFLAG_IN_LBAH, IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT | IDE_TFLAG_IN_LBA, - IDE_TFLAG_IN_DEVICE = (1 << 25), + IDE_TFLAG_IN_DEVICE = (1 << 29), IDE_TFLAG_HOB = IDE_TFLAG_OUT_HOB | IDE_TFLAG_IN_HOB, IDE_TFLAG_TF = IDE_TFLAG_OUT_TF | @@ -294,18 +309,9 @@ enum { IDE_TFLAG_DEVICE = IDE_TFLAG_OUT_DEVICE | IDE_TFLAG_IN_DEVICE, /* force 16-bit I/O operations */ - IDE_TFLAG_IO_16BIT = (1 << 26), - /* struct ide_cmd was allocated using kmalloc() */ - IDE_TFLAG_DYN = (1 << 27), - IDE_TFLAG_FS = (1 << 28), - IDE_TFLAG_MULTI_PIO = (1 << 29), -}; - -enum { - IDE_FTFLAG_FLAGGED = (1 << 0), - IDE_FTFLAG_SET_IN_FLAGS = (1 << 1), - IDE_FTFLAG_OUT_DATA = (1 << 2), - IDE_FTFLAG_IN_DATA = (1 << 3), + IDE_TFLAG_IO_16BIT = (1 << 30), + /* ide_task_t was allocated using kmalloc() */ + IDE_TFLAG_DYN = (1 << 31), }; struct ide_taskfile { @@ -337,27 +343,16 @@ struct ide_taskfile { }; }; -struct ide_cmd { +typedef struct ide_task_s { union { struct ide_taskfile tf; u8 tf_array[14]; }; - u8 ftf_flags; /* for TASKFILE ioctl */ u32 tf_flags; - int protocol; - - int sg_nents; /* number of sg entries */ - int orig_sg_nents; - int sg_dma_direction; /* DMA transfer direction */ - - unsigned int nbytes; - unsigned int nleft; - struct scatterlist *cursg; - unsigned int cursg_ofs; - + int data_phase; struct request *rq; /* copy of request */ void *special; /* valid_t generally */ -}; +} ide_task_t; /* ATAPI packet command flags */ enum { @@ -369,6 +364,8 @@ enum { PC_FLAG_DMA_IN_PROGRESS = (1 << 4), PC_FLAG_DMA_ERROR = (1 << 5), PC_FLAG_WRITING = (1 << 6), + /* command timed out */ + PC_FLAG_TIMEDOUT = (1 << 7), }; /* @@ -439,6 +436,7 @@ struct ide_disk_ops { int); ide_startstop_t (*do_request)(struct ide_drive_s *, struct request *, sector_t); + int (*end_request)(struct ide_drive_s *, int, int); int (*ioctl)(struct ide_drive_s *, struct block_device *, fmode_t, unsigned int, unsigned long); }; @@ -514,6 +512,8 @@ enum { IDE_DFLAG_NICE1 = (1 << 5), /* device is physically present */ IDE_DFLAG_PRESENT = (1 << 6), + /* device ejected hint */ + IDE_DFLAG_DEAD = (1 << 7), /* id read from device (synthetic if not set) */ IDE_DFLAG_ID_READ = (1 << 8), IDE_DFLAG_NOPROBE = (1 << 9), @@ -627,11 +627,8 @@ struct ide_drive_s { /* current packet command */ struct ide_atapi_pc *pc; - /* last failed packet command */ - struct ide_atapi_pc *failed_pc; - /* callback for packet commands */ - int (*pc_callback)(struct ide_drive_s *, int); + void (*pc_callback)(struct ide_drive_s *, int); void (*pc_update_buffers)(struct ide_drive_s *, struct ide_atapi_pc *); int (*pc_io_buffers)(struct ide_drive_s *, struct ide_atapi_pc *, @@ -664,13 +661,13 @@ struct ide_tp_ops { void (*set_irq)(struct hwif_s *, int); - void (*tf_load)(ide_drive_t *, struct ide_cmd *); - void (*tf_read)(ide_drive_t *, struct ide_cmd *); + void (*tf_load)(ide_drive_t *, struct ide_task_s *); + void (*tf_read)(ide_drive_t *, struct ide_task_s *); - void (*input_data)(ide_drive_t *, struct ide_cmd *, - void *, unsigned int); - void (*output_data)(ide_drive_t *, struct ide_cmd *, - void *, unsigned int); + void (*input_data)(ide_drive_t *, struct request *, void *, + unsigned int); + void (*output_data)(ide_drive_t *, struct request *, void *, + unsigned int); }; extern const struct ide_tp_ops default_tp_ops; @@ -714,12 +711,12 @@ struct ide_port_ops { struct ide_dma_ops { void (*dma_host_set)(struct ide_drive_s *, int); - int (*dma_setup)(struct ide_drive_s *, struct ide_cmd *); + int (*dma_setup)(struct ide_drive_s *); + void (*dma_exec_cmd)(struct ide_drive_s *, u8); void (*dma_start)(struct ide_drive_s *); int (*dma_end)(struct ide_drive_s *); int (*dma_test_irq)(struct ide_drive_s *); void (*dma_lost_irq)(struct ide_drive_s *); - int (*dma_timer_expiry)(struct ide_drive_s *); void (*dma_timeout)(struct ide_drive_s *); /* * The following method is optional and only required to be @@ -783,8 +780,19 @@ typedef struct hwif_s { /* Scatter-gather list used to build the above */ struct scatterlist *sg_table; int sg_max_nents; /* Maximum number of entries in it */ + int sg_nents; /* Current number of entries in it */ + int orig_sg_nents; + int sg_dma_direction; /* dma transfer direction */ + + /* data phase of the active command (currently only valid for PIO/DMA) */ + int data_phase; - struct ide_cmd cmd; /* current command */ + struct ide_task_s task; /* current command */ + + unsigned int nsect; + unsigned int nleft; + struct scatterlist *cursg; + unsigned int cursg_ofs; int rqsize; /* max sectors per request */ int irq; /* our irq number */ @@ -842,18 +850,9 @@ struct ide_host { ide_hwif_t *ports[MAX_HOST_PORTS + 1]; unsigned int n_ports; struct device *dev[2]; - int (*init_chipset)(struct pci_dev *); - - void (*get_lock)(irq_handler_t, void *); - void (*release_lock)(void); - irq_handler_t irq_handler; - unsigned long host_flags; - - int irq_flags; - void *host_priv; ide_hwif_t *cur_port; /* for hosts requiring serialization */ @@ -870,7 +869,7 @@ typedef ide_startstop_t (ide_handler_t)(ide_drive_t *); typedef int (ide_expiry_t)(ide_drive_t *); /* used by ide-cd, ide-floppy, etc. */ -typedef void (xfer_func_t)(ide_drive_t *, struct ide_cmd *, void *, unsigned); +typedef void (xfer_func_t)(ide_drive_t *, struct request *rq, void *, unsigned); extern struct mutex ide_setting_mtx; @@ -1046,11 +1045,10 @@ enum { }; /* DRV_NAME has to be defined in the driver before using the macro below */ -#define __ide_debug_log(lvl, fmt, args...) \ -{ \ - if (unlikely(drive->debug_mask & lvl)) \ - printk(KERN_INFO DRV_NAME ": %s: " fmt "\n", \ - __func__, ## args); \ +#define __ide_debug_log(lvl, fmt, args...) \ +{ \ + if (unlikely(drive->debug_mask & lvl)) \ + printk(KERN_INFO DRV_NAME ": " fmt, ## args); \ } /* @@ -1089,7 +1087,7 @@ int generic_ide_resume(struct device *); void ide_complete_power_step(ide_drive_t *, struct request *); ide_startstop_t ide_start_power_step(ide_drive_t *, struct request *); -void ide_complete_pm_rq(ide_drive_t *, struct request *); +void ide_complete_pm_request(ide_drive_t *, struct request *); void ide_check_pm_state(ide_drive_t *, struct request *); /* @@ -1101,6 +1099,7 @@ void ide_check_pm_state(ide_drive_t *, struct request *); struct ide_driver { const char *version; ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t); + int (*end_request)(ide_drive_t *, int, int); struct device_driver gen_driver; int (*probe)(ide_drive_t *); void (*remove)(ide_drive_t *); @@ -1131,15 +1130,19 @@ int generic_ide_ioctl(ide_drive_t *, struct block_device *, unsigned, unsigned l extern int ide_vlb_clk; extern int ide_pci_clk; -unsigned int ide_rq_bytes(struct request *); -int ide_end_rq(ide_drive_t *, struct request *, int, unsigned int); +int ide_end_request(ide_drive_t *, int, int); +int ide_end_dequeued_request(ide_drive_t *, struct request *, int, int); void ide_kill_rq(ide_drive_t *, struct request *); -void __ide_set_handler(ide_drive_t *, ide_handler_t *, unsigned int); -void ide_set_handler(ide_drive_t *, ide_handler_t *, unsigned int); +void __ide_set_handler(ide_drive_t *, ide_handler_t *, unsigned int, + ide_expiry_t *); +void ide_set_handler(ide_drive_t *, ide_handler_t *, unsigned int, + ide_expiry_t *); + +void ide_execute_command(ide_drive_t *, u8, ide_handler_t *, unsigned int, + ide_expiry_t *); -void ide_execute_command(ide_drive_t *, struct ide_cmd *, ide_handler_t *, - unsigned int); +void ide_execute_pkt_cmd(ide_drive_t *); void ide_pad_transfer(ide_drive_t *, int, int); @@ -1161,8 +1164,7 @@ extern ide_startstop_t ide_do_reset (ide_drive_t *); extern int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting, int arg); -void ide_complete_cmd(ide_drive_t *, struct ide_cmd *, u8, u8); -int ide_complete_rq(ide_drive_t *, int, unsigned int); +extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); void ide_tf_dump(const char *, struct ide_taskfile *); @@ -1172,11 +1174,11 @@ u8 ide_read_altstatus(ide_hwif_t *); void ide_set_irq(ide_hwif_t *, int); -void ide_tf_load(ide_drive_t *, struct ide_cmd *); -void ide_tf_read(ide_drive_t *, struct ide_cmd *); +void ide_tf_load(ide_drive_t *, ide_task_t *); +void ide_tf_read(ide_drive_t *, ide_task_t *); -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); +void ide_input_data(ide_drive_t *, struct request *, void *, unsigned int); +void ide_output_data(ide_drive_t *, struct request *, void *, unsigned int); int ide_io_buffers(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int); @@ -1222,16 +1224,16 @@ int ide_cd_expiry(ide_drive_t *); int ide_cd_get_xferlen(struct request *); -ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_cmd *); +ide_startstop_t ide_issue_pc(ide_drive_t *); -ide_startstop_t do_rw_taskfile(ide_drive_t *, struct ide_cmd *); +ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); -void ide_finish_cmd(ide_drive_t *, struct ide_cmd *, u8); +void task_end_request(ide_drive_t *, struct request *, u8); -int ide_raw_taskfile(ide_drive_t *, struct ide_cmd *, u8 *, u16); -int ide_no_data_taskfile(ide_drive_t *, struct ide_cmd *); +int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16); +int ide_no_data_taskfile(ide_drive_t *, ide_task_t *); -int ide_taskfile_ioctl(ide_drive_t *, unsigned long); +int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long); int ide_dev_read_id(ide_drive_t *, u8, u16 *); @@ -1333,10 +1335,6 @@ enum { IDE_HFLAG_ERROR_STOPS_FIFO = (1 << 19), /* serialize ports */ IDE_HFLAG_SERIALIZE = (1 << 20), - /* host is DTC2278 */ - IDE_HFLAG_DTC2278 = (1 << 21), - /* 4 devices on a single set of I/O ports */ - IDE_HFLAG_4DRIVES = (1 << 22), /* host is TRM290 */ IDE_HFLAG_TRM290 = (1 << 23), /* use 32-bit I/O ops */ @@ -1364,12 +1362,7 @@ enum { struct ide_port_info { char *name; - int (*init_chipset)(struct pci_dev *); - - void (*get_lock)(irq_handler_t, void *); - void (*release_lock)(void); - void (*init_iops)(ide_hwif_t *); void (*init_hwif)(ide_hwif_t *); int (*init_dma)(ide_hwif_t *, @@ -1386,9 +1379,6 @@ struct ide_port_info { u16 max_sectors; /* if < than the default one */ u32 host_flags; - - int irq_flags; - u8 pio_mask; u8 swdma_mask; u8 mwdma_mask; @@ -1408,8 +1398,8 @@ int ide_pci_resume(struct pci_dev *); #define ide_pci_resume NULL #endif -void ide_map_sg(ide_drive_t *, struct ide_cmd *); -void ide_init_sg_cmd(struct ide_cmd *, unsigned int); +void ide_map_sg(ide_drive_t *, struct request *); +void ide_init_sg_cmd(ide_drive_t *, struct request *); #define BAD_DMA_DRIVE 0 #define GOOD_DMA_DRIVE 1 @@ -1443,18 +1433,18 @@ 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 *); +int ide_build_sglist(ide_drive_t *, struct request *); void ide_destroy_dmatable(ide_drive_t *); #ifdef CONFIG_BLK_DEV_IDEDMA_SFF int config_drive_for_dma(ide_drive_t *); -int ide_build_dmatable(ide_drive_t *, struct ide_cmd *); +extern int ide_build_dmatable(ide_drive_t *, struct request *); void ide_dma_host_set(ide_drive_t *, int); -int ide_dma_setup(ide_drive_t *, struct ide_cmd *); +extern int ide_dma_setup(ide_drive_t *); +void ide_dma_exec_cmd(ide_drive_t *, u8); extern void ide_dma_start(ide_drive_t *); int ide_dma_end(ide_drive_t *); int ide_dma_test_irq(ide_drive_t *); -int ide_dma_sff_timer_expiry(ide_drive_t *); u8 ide_dma_sff_read_status(ide_hwif_t *); extern const struct ide_dma_ops sff_dma_ops; #else @@ -1475,11 +1465,8 @@ static inline void ide_dma_on(ide_drive_t *drive) { ; } static inline void ide_dma_verbose(ide_drive_t *drive) { ; } static inline int ide_set_dma(ide_drive_t *drive) { return 1; } static inline 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; } #endif /* CONFIG_BLK_DEV_IDEDMA */ #ifdef CONFIG_BLK_DEV_IDEACPI