Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[pandora-kernel.git] / drivers / ata / libata-sff.c
index e78ad76..19ddf92 100644 (file)
@@ -45,7 +45,7 @@ static struct workqueue_struct *ata_sff_wq;
 const struct ata_port_operations ata_sff_port_ops = {
        .inherits               = &ata_base_port_ops,
 
-       .qc_prep                = ata_sff_qc_prep,
+       .qc_prep                = ata_noop_qc_prep,
        .qc_issue               = ata_sff_qc_issue,
        .qc_fill_rtf            = ata_sff_qc_fill_rtf,
 
@@ -56,7 +56,6 @@ const struct ata_port_operations ata_sff_port_ops = {
        .hardreset              = sata_sff_hardreset,
        .postreset              = ata_sff_postreset,
        .error_handler          = ata_sff_error_handler,
-       .post_internal_cmd      = ata_sff_post_internal_cmd,
 
        .sff_dev_select         = ata_sff_dev_select,
        .sff_check_status       = ata_sff_check_status,
@@ -71,149 +70,6 @@ const struct ata_port_operations ata_sff_port_ops = {
 };
 EXPORT_SYMBOL_GPL(ata_sff_port_ops);
 
-/**
- *     ata_fill_sg - Fill PCI IDE PRD table
- *     @qc: Metadata associated with taskfile to be transferred
- *
- *     Fill PCI IDE PRD (scatter-gather) table with segments
- *     associated with the current disk command.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host lock)
- *
- */
-static void ata_fill_sg(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       struct scatterlist *sg;
-       unsigned int si, pi;
-
-       pi = 0;
-       for_each_sg(qc->sg, sg, qc->n_elem, si) {
-               u32 addr, offset;
-               u32 sg_len, len;
-
-               /* determine if physical DMA addr spans 64K boundary.
-                * Note h/w doesn't support 64-bit, so we unconditionally
-                * truncate dma_addr_t to u32.
-                */
-               addr = (u32) sg_dma_address(sg);
-               sg_len = sg_dma_len(sg);
-
-               while (sg_len) {
-                       offset = addr & 0xffff;
-                       len = sg_len;
-                       if ((offset + sg_len) > 0x10000)
-                               len = 0x10000 - offset;
-
-                       ap->prd[pi].addr = cpu_to_le32(addr);
-                       ap->prd[pi].flags_len = cpu_to_le32(len & 0xffff);
-                       VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len);
-
-                       pi++;
-                       sg_len -= len;
-                       addr += len;
-               }
-       }
-
-       ap->prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
-}
-
-/**
- *     ata_fill_sg_dumb - Fill PCI IDE PRD table
- *     @qc: Metadata associated with taskfile to be transferred
- *
- *     Fill PCI IDE PRD (scatter-gather) table with segments
- *     associated with the current disk command. Perform the fill
- *     so that we avoid writing any length 64K records for
- *     controllers that don't follow the spec.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host lock)
- *
- */
-static void ata_fill_sg_dumb(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       struct scatterlist *sg;
-       unsigned int si, pi;
-
-       pi = 0;
-       for_each_sg(qc->sg, sg, qc->n_elem, si) {
-               u32 addr, offset;
-               u32 sg_len, len, blen;
-
-               /* determine if physical DMA addr spans 64K boundary.
-                * Note h/w doesn't support 64-bit, so we unconditionally
-                * truncate dma_addr_t to u32.
-                */
-               addr = (u32) sg_dma_address(sg);
-               sg_len = sg_dma_len(sg);
-
-               while (sg_len) {
-                       offset = addr & 0xffff;
-                       len = sg_len;
-                       if ((offset + sg_len) > 0x10000)
-                               len = 0x10000 - offset;
-
-                       blen = len & 0xffff;
-                       ap->prd[pi].addr = cpu_to_le32(addr);
-                       if (blen == 0) {
-                               /* Some PATA chipsets like the CS5530 can't
-                                  cope with 0x0000 meaning 64K as the spec
-                                  says */
-                               ap->prd[pi].flags_len = cpu_to_le32(0x8000);
-                               blen = 0x8000;
-                               ap->prd[++pi].addr = cpu_to_le32(addr + 0x8000);
-                       }
-                       ap->prd[pi].flags_len = cpu_to_le32(blen);
-                       VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len);
-
-                       pi++;
-                       sg_len -= len;
-                       addr += len;
-               }
-       }
-
-       ap->prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
-}
-
-/**
- *     ata_sff_qc_prep - Prepare taskfile for submission
- *     @qc: Metadata associated with taskfile to be prepared
- *
- *     Prepare ATA taskfile for submission.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host lock)
- */
-void ata_sff_qc_prep(struct ata_queued_cmd *qc)
-{
-       if (!(qc->flags & ATA_QCFLAG_DMAMAP))
-               return;
-
-       ata_fill_sg(qc);
-}
-EXPORT_SYMBOL_GPL(ata_sff_qc_prep);
-
-/**
- *     ata_sff_dumb_qc_prep - Prepare taskfile for submission
- *     @qc: Metadata associated with taskfile to be prepared
- *
- *     Prepare ATA taskfile for submission.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host lock)
- */
-void ata_sff_dumb_qc_prep(struct ata_queued_cmd *qc)
-{
-       if (!(qc->flags & ATA_QCFLAG_DMAMAP))
-               return;
-
-       ata_fill_sg_dumb(qc);
-}
-EXPORT_SYMBOL_GPL(ata_sff_dumb_qc_prep);
-
 /**
  *     ata_sff_check_status - Read device status reg & clear interrupt
  *     @ap: port where the device is
@@ -1523,15 +1379,11 @@ fsm_start:
 }
 
 /**
- *     ata_sff_qc_issue - issue taskfile to device in proto-dependent manner
+ *     ata_sff_qc_issue - issue taskfile to a SFF controller
  *     @qc: command to issue to device
  *
- *     Using various libata functions and hooks, this function
- *     starts an ATA command.  ATA commands are grouped into
- *     classes called "protocols", and issuing each type of protocol
- *     is slightly different.
- *
- *     May be used as the qc_issue() entry in ata_port_operations.
+ *     This function issues a PIO or NODATA command to a SFF
+ *     controller.
  *
  *     LOCKING:
  *     spin_lock_irqsave(host lock)
@@ -1546,23 +1398,8 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
        /* Use polling pio if the LLD doesn't handle
         * interrupt driven pio and atapi CDB interrupt.
         */
-       if (ap->flags & ATA_FLAG_PIO_POLLING) {
-               switch (qc->tf.protocol) {
-               case ATA_PROT_PIO:
-               case ATA_PROT_NODATA:
-               case ATAPI_PROT_PIO:
-               case ATAPI_PROT_NODATA:
-                       qc->tf.flags |= ATA_TFLAG_POLLING;
-                       break;
-               case ATAPI_PROT_DMA:
-                       if (qc->dev->flags & ATA_DFLAG_CDB_INTR)
-                               /* see ata_dma_blacklisted() */
-                               BUG();
-                       break;
-               default:
-                       break;
-               }
-       }
+       if (ap->flags & ATA_FLAG_PIO_POLLING)
+               qc->tf.flags |= ATA_TFLAG_POLLING;
 
        /* select the device */
        ata_dev_select(ap, qc->dev->devno, 1, 0);
@@ -1581,15 +1418,6 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
 
                break;
 
-       case ATA_PROT_DMA:
-               WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
-
-               ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
-               ap->ops->bmdma_setup(qc);           /* set up bmdma */
-               ap->ops->bmdma_start(qc);           /* initiate bmdma */
-               ap->hsm_task_state = HSM_ST_LAST;
-               break;
-
        case ATA_PROT_PIO:
                if (qc->tf.flags & ATA_TFLAG_POLLING)
                        ata_qc_set_polling(qc);
@@ -1634,18 +1462,6 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
                        ata_sff_queue_pio_task(ap, 0);
                break;
 
-       case ATAPI_PROT_DMA:
-               WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
-
-               ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
-               ap->ops->bmdma_setup(qc);           /* set up bmdma */
-               ap->hsm_task_state = HSM_ST_FIRST;
-
-               /* send cdb by polling if no cdb interrupt */
-               if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
-                       ata_sff_queue_pio_task(ap, 0);
-               break;
-
        default:
                WARN_ON_ONCE(1);
                return AC_ERR_SYSTEM;
@@ -2361,7 +2177,7 @@ void ata_sff_drain_fifo(struct ata_queued_cmd *qc)
 EXPORT_SYMBOL_GPL(ata_sff_drain_fifo);
 
 /**
- *     ata_sff_error_handler - Stock error handler for BMDMA controller
+ *     ata_sff_error_handler - Stock error handler for SFF controller
  *     @ap: port to handle error for
  *
  *     Stock error handler for SFF controller.  It can handle both
@@ -2378,64 +2194,32 @@ void ata_sff_error_handler(struct ata_port *ap)
        ata_reset_fn_t hardreset = ap->ops->hardreset;
        struct ata_queued_cmd *qc;
        unsigned long flags;
-       bool thaw = false;
 
        qc = __ata_qc_from_tag(ap, ap->link.active_tag);
        if (qc && !(qc->flags & ATA_QCFLAG_FAILED))
                qc = NULL;
 
-       /* reset PIO HSM and stop DMA engine */
        spin_lock_irqsave(ap->lock, flags);
 
-       if (ap->ioaddr.bmdma_addr &&
-           qc && (qc->tf.protocol == ATA_PROT_DMA ||
-                  qc->tf.protocol == ATAPI_PROT_DMA)) {
-               u8 host_stat;
-
-               host_stat = ap->ops->bmdma_status(ap);
-
-               /* BMDMA controllers indicate host bus error by
-                * setting DMA_ERR bit and timing out.  As it wasn't
-                * really a timeout event, adjust error mask and
-                * cancel frozen state.
-                */
-               if (qc->err_mask == AC_ERR_TIMEOUT
-                                               && (host_stat & ATA_DMA_ERR)) {
-                       qc->err_mask = AC_ERR_HOST_BUS;
-                       thaw = true;
-               }
-
-               ap->ops->bmdma_stop(qc);
-
-               /* if we're gonna thaw, make sure IRQ is clear */
-               if (thaw) {
-                       ap->ops->sff_check_status(ap);
-                       ap->ops->sff_irq_clear(ap);
-
-                       spin_unlock_irqrestore(ap->lock, flags);
-                       ata_eh_thaw_port(ap);
-                       spin_lock_irqsave(ap->lock, flags);
-               }
-       }
-
-       /* We *MUST* do FIFO draining before we issue a reset as several
-        * devices helpfully clear their internal state and will lock solid
-        * if we touch the data port post reset. Pass qc in case anyone wants
-        *  to do different PIO/DMA recovery or has per command fixups
+       /*
+        * We *MUST* do FIFO draining before we issue a reset as
+        * several devices helpfully clear their internal state and
+        * will lock solid if we touch the data port post reset. Pass
+        * qc in case anyone wants to do different PIO/DMA recovery or
+        * has per command fixups
         */
        if (ap->ops->sff_drain_fifo)
                ap->ops->sff_drain_fifo(qc);
 
        spin_unlock_irqrestore(ap->lock, flags);
 
-       /* PIO and DMA engines have been stopped, perform recovery */
-
-       /* Ignore ata_sff_softreset if ctl isn't accessible and
-        * built-in hardresets if SCR access isn't available.
-        */
+       /* ignore ata_sff_softreset if ctl isn't accessible */
        if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr)
                softreset = NULL;
-       if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link))
+
+       /* ignore built-in hardresets if SCR access is not available */
+       if ((hardreset == sata_std_hardreset ||
+            hardreset == sata_sff_hardreset) && !sata_scr_valid(&ap->link))
                hardreset = NULL;
 
        ata_do_eh(ap, ap->ops->prereset, softreset, hardreset,
@@ -2443,27 +2227,6 @@ void ata_sff_error_handler(struct ata_port *ap)
 }
 EXPORT_SYMBOL_GPL(ata_sff_error_handler);
 
-/**
- *     ata_sff_post_internal_cmd - Stock post_internal_cmd for SFF controller
- *     @qc: internal command to clean up
- *
- *     LOCKING:
- *     Kernel thread context (may sleep)
- */
-void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       unsigned long flags;
-
-       spin_lock_irqsave(ap->lock, flags);
-
-       if (ap->ioaddr.bmdma_addr)
-               ap->ops->bmdma_stop(qc);
-
-       spin_unlock_irqrestore(ap->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd);
-
 /**
  *     ata_sff_std_ports - initialize ioaddr with standard port offsets.
  *     @ioaddr: IO address structure to be initialized
@@ -2811,6 +2574,12 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
 const struct ata_port_operations ata_bmdma_port_ops = {
        .inherits               = &ata_sff_port_ops,
 
+       .error_handler          = ata_bmdma_error_handler,
+       .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+
+       .qc_prep                = ata_bmdma_qc_prep,
+       .qc_issue               = ata_bmdma_qc_issue,
+
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
        .bmdma_stop             = ata_bmdma_stop,
@@ -2828,6 +2597,290 @@ const struct ata_port_operations ata_bmdma32_port_ops = {
 };
 EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);
 
+/**
+ *     ata_bmdma_fill_sg - Fill PCI IDE PRD table
+ *     @qc: Metadata associated with taskfile to be transferred
+ *
+ *     Fill PCI IDE PRD (scatter-gather) table with segments
+ *     associated with the current disk command.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ *
+ */
+static void ata_bmdma_fill_sg(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct ata_bmdma_prd *prd = ap->bmdma_prd;
+       struct scatterlist *sg;
+       unsigned int si, pi;
+
+       pi = 0;
+       for_each_sg(qc->sg, sg, qc->n_elem, si) {
+               u32 addr, offset;
+               u32 sg_len, len;
+
+               /* determine if physical DMA addr spans 64K boundary.
+                * Note h/w doesn't support 64-bit, so we unconditionally
+                * truncate dma_addr_t to u32.
+                */
+               addr = (u32) sg_dma_address(sg);
+               sg_len = sg_dma_len(sg);
+
+               while (sg_len) {
+                       offset = addr & 0xffff;
+                       len = sg_len;
+                       if ((offset + sg_len) > 0x10000)
+                               len = 0x10000 - offset;
+
+                       prd[pi].addr = cpu_to_le32(addr);
+                       prd[pi].flags_len = cpu_to_le32(len & 0xffff);
+                       VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len);
+
+                       pi++;
+                       sg_len -= len;
+                       addr += len;
+               }
+       }
+
+       prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+}
+
+/**
+ *     ata_bmdma_fill_sg_dumb - Fill PCI IDE PRD table
+ *     @qc: Metadata associated with taskfile to be transferred
+ *
+ *     Fill PCI IDE PRD (scatter-gather) table with segments
+ *     associated with the current disk command. Perform the fill
+ *     so that we avoid writing any length 64K records for
+ *     controllers that don't follow the spec.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ *
+ */
+static void ata_bmdma_fill_sg_dumb(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct ata_bmdma_prd *prd = ap->bmdma_prd;
+       struct scatterlist *sg;
+       unsigned int si, pi;
+
+       pi = 0;
+       for_each_sg(qc->sg, sg, qc->n_elem, si) {
+               u32 addr, offset;
+               u32 sg_len, len, blen;
+
+               /* determine if physical DMA addr spans 64K boundary.
+                * Note h/w doesn't support 64-bit, so we unconditionally
+                * truncate dma_addr_t to u32.
+                */
+               addr = (u32) sg_dma_address(sg);
+               sg_len = sg_dma_len(sg);
+
+               while (sg_len) {
+                       offset = addr & 0xffff;
+                       len = sg_len;
+                       if ((offset + sg_len) > 0x10000)
+                               len = 0x10000 - offset;
+
+                       blen = len & 0xffff;
+                       prd[pi].addr = cpu_to_le32(addr);
+                       if (blen == 0) {
+                               /* Some PATA chipsets like the CS5530 can't
+                                  cope with 0x0000 meaning 64K as the spec
+                                  says */
+                               prd[pi].flags_len = cpu_to_le32(0x8000);
+                               blen = 0x8000;
+                               prd[++pi].addr = cpu_to_le32(addr + 0x8000);
+                       }
+                       prd[pi].flags_len = cpu_to_le32(blen);
+                       VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len);
+
+                       pi++;
+                       sg_len -= len;
+                       addr += len;
+               }
+       }
+
+       prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+}
+
+/**
+ *     ata_bmdma_qc_prep - Prepare taskfile for submission
+ *     @qc: Metadata associated with taskfile to be prepared
+ *
+ *     Prepare ATA taskfile for submission.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ */
+void ata_bmdma_qc_prep(struct ata_queued_cmd *qc)
+{
+       if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+               return;
+
+       ata_bmdma_fill_sg(qc);
+}
+EXPORT_SYMBOL_GPL(ata_bmdma_qc_prep);
+
+/**
+ *     ata_bmdma_dumb_qc_prep - Prepare taskfile for submission
+ *     @qc: Metadata associated with taskfile to be prepared
+ *
+ *     Prepare ATA taskfile for submission.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ */
+void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc)
+{
+       if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+               return;
+
+       ata_bmdma_fill_sg_dumb(qc);
+}
+EXPORT_SYMBOL_GPL(ata_bmdma_dumb_qc_prep);
+
+/**
+ *     ata_bmdma_qc_issue - issue taskfile to a BMDMA controller
+ *     @qc: command to issue to device
+ *
+ *     This function issues a PIO, NODATA or DMA command to a
+ *     SFF/BMDMA controller.  PIO and NODATA are handled by
+ *     ata_sff_qc_issue().
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ *
+ *     RETURNS:
+ *     Zero on success, AC_ERR_* mask on failure
+ */
+unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+
+       /* see ata_dma_blacklisted() */
+       BUG_ON((ap->flags & ATA_FLAG_PIO_POLLING) &&
+              qc->tf.protocol == ATAPI_PROT_DMA);
+
+       /* defer PIO handling to sff_qc_issue */
+       if (!ata_is_dma(qc->tf.protocol))
+               return ata_sff_qc_issue(qc);
+
+       /* select the device */
+       ata_dev_select(ap, qc->dev->devno, 1, 0);
+
+       /* start the command */
+       switch (qc->tf.protocol) {
+       case ATA_PROT_DMA:
+               WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
+
+               ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
+               ap->ops->bmdma_setup(qc);           /* set up bmdma */
+               ap->ops->bmdma_start(qc);           /* initiate bmdma */
+               ap->hsm_task_state = HSM_ST_LAST;
+               break;
+
+       case ATAPI_PROT_DMA:
+               WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
+
+               ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
+               ap->ops->bmdma_setup(qc);           /* set up bmdma */
+               ap->hsm_task_state = HSM_ST_FIRST;
+
+               /* send cdb by polling if no cdb interrupt */
+               if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
+                       ata_sff_queue_pio_task(ap, 0);
+               break;
+
+       default:
+               WARN_ON(1);
+               return AC_ERR_SYSTEM;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue);
+
+/**
+ *     ata_bmdma_error_handler - Stock error handler for BMDMA controller
+ *     @ap: port to handle error for
+ *
+ *     Stock error handler for BMDMA controller.  It can handle both
+ *     PATA and SATA controllers.  Most BMDMA controllers should be
+ *     able to use this EH as-is or with some added handling before
+ *     and after.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ */
+void ata_bmdma_error_handler(struct ata_port *ap)
+{
+       struct ata_queued_cmd *qc;
+       unsigned long flags;
+       bool thaw = false;
+
+       qc = __ata_qc_from_tag(ap, ap->link.active_tag);
+       if (qc && !(qc->flags & ATA_QCFLAG_FAILED))
+               qc = NULL;
+
+       /* reset PIO HSM and stop DMA engine */
+       spin_lock_irqsave(ap->lock, flags);
+
+       if (qc && ata_is_dma(qc->tf.protocol)) {
+               u8 host_stat;
+
+               host_stat = ap->ops->bmdma_status(ap);
+
+               /* BMDMA controllers indicate host bus error by
+                * setting DMA_ERR bit and timing out.  As it wasn't
+                * really a timeout event, adjust error mask and
+                * cancel frozen state.
+                */
+               if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) {
+                       qc->err_mask = AC_ERR_HOST_BUS;
+                       thaw = true;
+               }
+
+               ap->ops->bmdma_stop(qc);
+
+               /* if we're gonna thaw, make sure IRQ is clear */
+               if (thaw) {
+                       ap->ops->sff_check_status(ap);
+                       ap->ops->sff_irq_clear(ap);
+               }
+       }
+
+       spin_unlock_irqrestore(ap->lock, flags);
+
+       if (thaw)
+               ata_eh_thaw_port(ap);
+
+       ata_sff_error_handler(ap);
+}
+EXPORT_SYMBOL_GPL(ata_bmdma_error_handler);
+
+/**
+ *     ata_bmdma_post_internal_cmd - Stock post_internal_cmd for BMDMA
+ *     @qc: internal command to clean up
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ */
+void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       unsigned long flags;
+
+       if (ata_is_dma(qc->tf.protocol)) {
+               spin_lock_irqsave(ap->lock, flags);
+               ap->ops->bmdma_stop(qc);
+               spin_unlock_irqrestore(ap->lock, flags);
+       }
+}
+EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
+
 /**
  *     ata_bmdma_setup - Set up PCI IDE BMDMA transaction
  *     @qc: Info associated with this ATA transaction.
@@ -2843,7 +2896,7 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)
 
        /* load PRD table addr. */
        mb();   /* make sure PRD table writes are visible to controller */
-       iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
+       iowrite32(ap->bmdma_prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
 
        /* specify data direction, triple-check start bit is clear */
        dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
@@ -2948,9 +3001,10 @@ EXPORT_SYMBOL_GPL(ata_bmdma_status);
 int ata_bmdma_port_start(struct ata_port *ap)
 {
        if (ap->mwdma_mask || ap->udma_mask) {
-               ap->prd = dmam_alloc_coherent(ap->host->dev, ATA_PRD_TBL_SZ,
-                                             &ap->prd_dma, GFP_KERNEL);
-               if (!ap->prd)
+               ap->bmdma_prd =
+                       dmam_alloc_coherent(ap->host->dev, ATA_PRD_TBL_SZ,
+                                           &ap->bmdma_prd_dma, GFP_KERNEL);
+               if (!ap->bmdma_prd)
                        return -ENOMEM;
        }