--- linux-2.6.20-rc5/drivers/ata/sata_nv.c 2007-01-19 19:18:53.000000000 -0600 +++ linux-2.6.20-rc5debug/drivers/ata/sata_nv.c 2007-01-19 20:25:31.000000000 -0600 @@ -245,6 +245,7 @@ static void nv_adma_bmdma_setup(struct a static void nv_adma_bmdma_start(struct ata_queued_cmd *qc); static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc); static u8 nv_adma_bmdma_status(struct ata_port *ap); +static void nv_adma_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); enum nv_host_type { @@ -409,7 +410,7 @@ static const struct ata_port_operations .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_atapi_dma = nv_adma_check_atapi_dma, - .exec_command = ata_exec_command, + .exec_command = nv_adma_exec_command, .check_status = ata_check_status, .dev_select = ata_std_dev_select, .bmdma_setup = nv_adma_bmdma_setup, @@ -617,6 +618,14 @@ static int nv_adma_check_atapi_dma(struc return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE); } +static void nv_adma_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) +{ + void __iomem* mmio = nv_adma_ctl_block(ap); + writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr); + readw(mmio + NV_ADMA_CTL); /* flush */ + ndelay(400); +} + static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb) { unsigned int idx = 0; @@ -701,6 +710,9 @@ static int nv_host_intr(struct ata_port { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); int handled; + u8 cmd = 0; + if(qc) + cmd = qc->tf.command; /* freeze if hotplugged */ if (unlikely(irq_stat & (NV_INT_ADDED | NV_INT_REMOVED))) { @@ -709,8 +721,11 @@ static int nv_host_intr(struct ata_port } /* bail out if not our interrupt */ - if (!(irq_stat & NV_INT_DEV)) + if (!(irq_stat & NV_INT_DEV)) { + if( cmd == ATA_CMD_FLUSH || cmd == ATA_CMD_FLUSH_EXT ) + ata_port_printk(ap, KERN_NOTICE, "cmd 0x%x active but stat 0x%x\n", cmd, irq_stat); return 0; + } /* DEV interrupt w/ no active qc? */ if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) { @@ -720,6 +735,8 @@ static int nv_host_intr(struct ata_port /* handle interrupt */ handled = ata_host_intr(ap, qc); + if( cmd == ATA_CMD_FLUSH || cmd == ATA_CMD_FLUSH_EXT ) + ata_port_printk(ap, KERN_NOTICE, "cmd 0x%x active, stat = 0x%x, handled = 0x%x\n", cmd, irq_stat, handled); if (unlikely(!handled)) { /* spurious, clear it */ ata_check_status(ap); @@ -870,7 +887,7 @@ static void nv_adma_bmdma_setup(struct a outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD); /* issue r/w command */ - ata_exec_command(ap, &qc->tf); + nv_adma_exec_command(ap, &qc->tf); } static void nv_adma_bmdma_start(struct ata_queued_cmd *qc) @@ -1161,6 +1178,9 @@ static unsigned int nv_adma_qc_issue(str /* use ATA register mode */ VPRINTK("no dmamap or ATAPI, using ATA register mode: 0x%lx\n", qc->flags); nv_adma_register_mode(qc->ap); + if(qc->tf.command == ATA_CMD_FLUSH || + qc->tf.command == ATA_CMD_FLUSH_EXT ) + ata_port_printk(qc->ap, KERN_NOTICE, "issue flush cmd 0x%x\n", qc->tf.command); return ata_qc_issue_prot(qc); } else nv_adma_mode(qc->ap);