Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[safe/jmp/linux-2.6] / drivers / ata / sata_sil.c
index 35bd5cc..3a4f842 100644 (file)
@@ -284,7 +284,7 @@ static void sil_bmdma_setup(struct ata_queued_cmd *qc)
        void __iomem *bmdma = ap->ioaddr.bmdma_addr;
 
        /* load PRD table addr. */
-       iowrite32(ap->prd_dma, bmdma + ATA_DMA_TABLE_OFS);
+       iowrite32(ap->bmdma_prd_dma, bmdma + ATA_DMA_TABLE_OFS);
 
        /* issue r/w command */
        ap->ops->sff_exec_command(ap, &qc->tf);
@@ -311,10 +311,10 @@ static void sil_fill_sg(struct ata_queued_cmd *qc)
 {
        struct scatterlist *sg;
        struct ata_port *ap = qc->ap;
-       struct ata_prd *prd, *last_prd = NULL;
+       struct ata_bmdma_prd *prd, *last_prd = NULL;
        unsigned int si;
 
-       prd = &ap->prd[0];
+       prd = &ap->bmdma_prd[0];
        for_each_sg(qc->sg, sg, qc->n_elem, si) {
                /* Note h/w doesn't support 64-bit, so we unconditionally
                 * truncate dma_addr_t to u32.
@@ -503,7 +503,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
                goto err_hsm;
 
        /* ack bmdma irq events */
-       ata_sff_irq_clear(ap);
+       ata_bmdma_irq_clear(ap);
 
        /* kick HSM in the ass */
        ata_sff_hsm_move(ap, qc, status, 0);
@@ -532,9 +532,6 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance)
                struct ata_port *ap = host->ports[i];
                u32 bmdma2 = readl(mmio_base + sil_port[ap->port_no].bmdma2);
 
-               if (unlikely(ap->flags & ATA_FLAG_DISABLED))
-                       continue;
-
                /* turn off SATA_IRQ if not supported */
                if (ap->flags & SIL_FLAG_NO_SATA_IRQ)
                        bmdma2 &= ~SIL_DMA_SATA_IRQ;
@@ -565,6 +562,19 @@ static void sil_freeze(struct ata_port *ap)
        tmp |= SIL_MASK_IDE0_INT << ap->port_no;
        writel(tmp, mmio_base + SIL_SYSCFG);
        readl(mmio_base + SIL_SYSCFG);  /* flush */
+
+       /* Ensure DMA_ENABLE is off.
+        *
+        * This is because the controller will not give us access to the
+        * taskfile registers while a DMA is in progress
+        */
+       iowrite8(ioread8(ap->ioaddr.bmdma_addr) & ~SIL_DMA_ENABLE,
+                ap->ioaddr.bmdma_addr);
+
+       /* According to ata_bmdma_stop, an HDMA transition requires
+        * on PIO cycle. But we can't read a taskfile register.
+        */
+       ioread8(ap->ioaddr.bmdma_addr);
 }
 
 static void sil_thaw(struct ata_port *ap)
@@ -574,7 +584,7 @@ static void sil_thaw(struct ata_port *ap)
 
        /* clear IRQ */
        ap->ops->sff_check_status(ap);
-       ata_sff_irq_clear(ap);
+       ata_bmdma_irq_clear(ap);
 
        /* turn on SATA IRQ if supported */
        if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ))