}
 #endif
 
-/**
- *     ata_port_start - Set port up for dma.
- *     @ap: Port to initialize
- *
- *     Called just after data structures for each port are
- *     initialized.  Allocates space for PRD table.
- *
- *     May be used as the port_start() entry in ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-int ata_port_start(struct ata_port *ap)
-{
-       struct device *dev = ap->dev;
-
-       ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
-                                     GFP_KERNEL);
-       if (!ap->prd)
-               return -ENOMEM;
-
-       return 0;
-}
-
 /**
  *     ata_dev_init - Initialize an ata_device structure
  *     @dev: Device structure to initialize
 EXPORT_SYMBOL_GPL(ata_xfer_mode2shift);
 EXPORT_SYMBOL_GPL(ata_mode_string);
 EXPORT_SYMBOL_GPL(ata_id_xfermask);
-EXPORT_SYMBOL_GPL(ata_port_start);
 EXPORT_SYMBOL_GPL(ata_do_set_mode);
 EXPORT_SYMBOL_GPL(ata_std_qc_defer);
 EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
 
        .sff_irq_clear          = ata_sff_irq_clear,
 
        .lost_interrupt         = ata_sff_lost_interrupt,
-
-       .port_start             = ata_sff_port_start,
 };
 EXPORT_SYMBOL_GPL(ata_sff_port_ops);
 
 }
 EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd);
 
-/**
- *     ata_sff_port_start - Set port up for dma.
- *     @ap: Port to initialize
- *
- *     Called just after data structures for each port are
- *     initialized.  Allocates space for PRD table if the device
- *     is DMA capable SFF.
- *
- *     May be used as the port_start() entry in ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-int ata_sff_port_start(struct ata_port *ap)
-{
-       if (ap->ioaddr.bmdma_addr)
-               return ata_port_start(ap);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(ata_sff_port_start);
-
-/**
- *     ata_sff_port_start32 - Set port up for dma.
- *     @ap: Port to initialize
- *
- *     Called just after data structures for each port are
- *     initialized.  Allocates space for PRD table if the device
- *     is DMA capable SFF.
- *
- *     May be used as the port_start() entry in ata_port_operations for
- *     devices that are capable of 32bit PIO.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-int ata_sff_port_start32(struct ata_port *ap)
-{
-       ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
-       if (ap->ioaddr.bmdma_addr)
-               return ata_port_start(ap);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(ata_sff_port_start32);
-
 /**
  *     ata_sff_std_ports - initialize ioaddr with standard port offsets.
  *     @ioaddr: IO address structure to be initialized
                goto err_out;
 
        /* init DMA related stuff */
-       rc = ata_pci_bmdma_init(host);
-       if (rc)
-               goto err_bmdma;
+       ata_pci_bmdma_init(host);
 
        devres_remove_group(&pdev->dev, NULL);
        *r_host = host;
        return 0;
 
-err_bmdma:
-       /* This is necessary because PCI and iomap resources are
-        * merged and releasing the top group won't release the
-        * acquired resources if some of those have been acquired
-        * before entering this function.
-        */
-       pcim_iounmap_regions(pdev, 0xf);
 err_out:
        devres_release_group(&pdev->dev, NULL);
        return rc;
 const struct ata_port_operations ata_bmdma_port_ops = {
        .inherits               = &ata_sff_port_ops,
 
-       .mode_filter            = ata_bmdma_mode_filter,
-
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
        .bmdma_stop             = ata_bmdma_stop,
        .bmdma_status           = ata_bmdma_status,
+
+       .port_start             = ata_bmdma_port_start,
 };
 EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
 
        .inherits               = &ata_bmdma_port_ops,
 
        .sff_data_xfer          = ata_sff_data_xfer32,
-       .port_start             = ata_sff_port_start32,
+       .port_start             = ata_bmdma_port_start32,
 };
 EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);
 
-unsigned long ata_bmdma_mode_filter(struct ata_device *adev,
-                                   unsigned long xfer_mask)
-{
-       /* Filter out DMA modes if the device has been configured by
-          the BIOS as PIO only */
-
-       if (adev->link->ap->ioaddr.bmdma_addr == NULL)
-               xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
-       return xfer_mask;
-}
-EXPORT_SYMBOL_GPL(ata_bmdma_mode_filter);
-
 /**
  *     ata_bmdma_setup - Set up PCI IDE BMDMA transaction
  *     @qc: Info associated with this ATA transaction.
 }
 EXPORT_SYMBOL_GPL(ata_bmdma_status);
 
+
+/**
+ *     ata_bmdma_port_start - Set port up for bmdma.
+ *     @ap: Port to initialize
+ *
+ *     Called just after data structures for each port are
+ *     initialized.  Allocates space for PRD table.
+ *
+ *     May be used as the port_start() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+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)
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ata_bmdma_port_start);
+
+/**
+ *     ata_bmdma_port_start32 - Set port up for dma.
+ *     @ap: Port to initialize
+ *
+ *     Called just after data structures for each port are
+ *     initialized.  Enables 32bit PIO and allocates space for PRD
+ *     table.
+ *
+ *     May be used as the port_start() entry in ata_port_operations for
+ *     devices that are capable of 32bit PIO.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+int ata_bmdma_port_start32(struct ata_port *ap)
+{
+       ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
+       return ata_bmdma_port_start(ap);
+}
+EXPORT_SYMBOL_GPL(ata_bmdma_port_start32);
+
 #ifdef CONFIG_PCI
 
 /**
 }
 EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex);
 
+static void ata_bmdma_nodma(struct ata_host *host, const char *reason)
+{
+       int i;
+
+       dev_printk(KERN_ERR, host->dev, "BMDMA: %s, falling back to PIO\n",
+                  reason);
+
+       for (i = 0; i < 2; i++) {
+               host->ports[i]->mwdma_mask = 0;
+               host->ports[i]->udma_mask = 0;
+       }
+}
+
 /**
  *     ata_pci_bmdma_init - acquire PCI BMDMA resources and init ATA host
  *     @host: target ATA host
  *
  *     LOCKING:
  *     Inherited from calling layer (may sleep).
- *
- *     RETURNS:
- *     0 on success, -errno otherwise.
  */
-int ata_pci_bmdma_init(struct ata_host *host)
+void ata_pci_bmdma_init(struct ata_host *host)
 {
        struct device *gdev = host->dev;
        struct pci_dev *pdev = to_pci_dev(gdev);
        int i, rc;
 
        /* No BAR4 allocation: No DMA */
-       if (pci_resource_start(pdev, 4) == 0)
-               return 0;
+       if (pci_resource_start(pdev, 4) == 0) {
+               ata_bmdma_nodma(host, "BAR4 is zero");
+               return;
+       }
 
-       /* TODO: If we get no DMA mask we should fall back to PIO */
+       /*
+        * Some controllers require BMDMA region to be initialized
+        * even if DMA is not in use to clear IRQ status via
+        * ->sff_irq_clear method.  Try to initialize bmdma_addr
+        * regardless of dma masks.
+        */
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
-               return rc;
-       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
+               ata_bmdma_nodma(host, "failed to set dma mask");
+       if (!rc) {
+               rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+               if (rc)
+                       ata_bmdma_nodma(host,
+                                       "failed to set consistent dma mask");
+       }
 
        /* request and iomap DMA region */
        rc = pcim_iomap_regions(pdev, 1 << 4, dev_driver_string(gdev));
        if (rc) {
-               dev_printk(KERN_ERR, gdev, "failed to request/iomap BAR4\n");
-               return -ENOMEM;
+               ata_bmdma_nodma(host, "failed to request/iomap BAR4");
+               return;
        }
        host->iomap = pcim_iomap_table(pdev);
 
                ata_port_desc(ap, "bmdma 0x%llx",
                    (unsigned long long)pci_resource_start(pdev, 4) + 8 * i);
        }
-
-       return 0;
 }
 EXPORT_SYMBOL_GPL(ata_pci_bmdma_init);
 
 
 static unsigned long pacpi_mode_filter(struct ata_device *adev, unsigned long mask)
 {
        struct pata_acpi *acpi = adev->link->ap->private_data;
-       return ata_bmdma_mode_filter(adev, mask & acpi->mask[adev->devno]);
+       return mask & acpi->mask[adev->devno];
 }
 
 /**
                return -ENOMEM;
        acpi->mask[0] = pacpi_discover_modes(ap, &ap->link.device[0]);
        acpi->mask[1] = pacpi_discover_modes(ap, &ap->link.device[1]);
-       ret = ata_sff_port_start(ap);
+       ret = ata_bmdma_port_start(ap);
        if (ret < 0)
                return ret;
 
 
        ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
        if (strstr(model_num, "WDC"))
                return mask &= ~ATA_MASK_UDMA;
-       return ata_bmdma_mode_filter(adev, mask);
+       return mask;
 }
 
 /**
 
        .sff_data_xfer  = pata_at91_data_xfer_noirq,
        .set_piomode    = pata_at91_set_piomode,
        .cable_detect   = ata_cable_40wire,
-       .port_start     = ATA_OP_NULL,
 };
 
 static int __devinit pata_at91_probe(struct platform_device *pdev)
 
 
        .port_start             = bfin_port_start,
        .port_stop              = bfin_port_stop,
-
-       .mode_filter            = ATA_OP_NULL,  /* will be removed soon */
 };
 
 static struct ata_port_info bfin_port_info[] = {
 
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        struct cmd640_reg *timing;
 
-       int ret = ata_sff_port_start(ap);
-       if (ret < 0)
-               return ret;
-
        timing = devm_kzalloc(&pdev->dev, sizeof(struct cmd640_reg), GFP_KERNEL);
        if (timing == NULL)
                return -ENOMEM;
        timing->last = -1;      /* Force a load */
        ap->private_data = timing;
-       return ret;
+       return 0;
 }
 
 static struct scsi_host_template cmd640_sht = {
 
        } else if (adev->class == ATA_DEV_ATAPI)
                mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
 
-       return ata_bmdma_mode_filter(adev, mask);
+       return mask;
 }
 
 static int hpt36x_cable_detect(struct ata_port *ap)
 
                if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
                        mask &= ~(0xE0 << ATA_SHIFT_UDMA);
        }
-       return ata_bmdma_mode_filter(adev, mask);
+       return mask;
 }
 
 /**
                if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
                        mask &= ~(0xE0 << ATA_SHIFT_UDMA);
        }
-       return ata_bmdma_mode_filter(adev, mask);
+       return mask;
 }
 
 /**
 
        .postreset              = pata_icside_postreset,
        .post_internal_cmd      = pata_icside_bmdma_stop,
 
-       .mode_filter            = ATA_OP_NULL,  /* will be removed soon */
+       .port_start             = ATA_OP_NULL,  /* don't need PRD table */
 };
 
 static void __devinit
 
        struct it821x_dev *itdev;
        u8 conf;
 
-       int ret = ata_sff_port_start(ap);
+       int ret = ata_bmdma_port_start(ap);
        if (ret < 0)
                return ret;
 
 
        if (priv->dma_table_cpu == NULL) {
                dev_err(priv->dev, "Unable to allocate DMA command list\n");
                ap->ioaddr.bmdma_addr = NULL;
+               ap->mwdma_mask = 0;
+               ap->udma_mask = 0;
        }
        return 0;
 }
 
        struct ata_device *pair = ata_dev_pair(adev);
 
        if (adev->class != ATA_DEV_ATA || adev->devno == 0 || pair == NULL)
-               return ata_bmdma_mode_filter(adev, mask);
+               return mask;
 
        /* Check for slave of a Maxtor at UDMA6 */
        ata_id_c_string(pair->id, model_num, ATA_ID_PROD,
        if (strstr(model_num, "Maxtor") == NULL && pair->dma_mode == XFER_UDMA_6)
                mask &= ~ (1 << (6 + ATA_SHIFT_UDMA));
 
-       return ata_bmdma_mode_filter(adev, mask);
+       return mask;
 }
 
 /**
 
                u8 burst = ioread8(bmdma + 0x1f);
                iowrite8(burst | 0x01, bmdma + 0x1f);
        }
-       return ata_sff_port_start(ap);
+       return ata_bmdma_port_start(ap);
 }
 
 /**
 
        .sff_data_xfer          = ata_sff_data_xfer_noirq,
        .cable_detect           = ata_cable_unknown,
        .set_mode               = pata_platform_set_mode,
-       .port_start             = ATA_OP_NULL,
 };
 
 static void pata_platform_setup_port(struct ata_ioports *ioaddr,
 
                printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME);
                mask &= ~(0xE0 << ATA_SHIFT_UDMA);
        }
-       return ata_bmdma_mode_filter(adev, mask);
+       return mask;
 }
 
 /**
  *     scc_port_start - Set port up for dma.
  *     @ap: Port to initialize
  *
- *     Allocate space for PRD table using ata_port_start().
+ *     Allocate space for PRD table using ata_bmdma_port_start().
  *     Set PRD table address for PTERADD. (PRD Transfer End Read)
  */
 
        void __iomem *mmio = ap->ioaddr.bmdma_addr;
        int rc;
 
-       rc = ata_port_start(ap);
+       rc = ata_bmdma_port_start(ap);
        if (rc)
                return rc;
 
 
 {
        if (adev->class == ATA_DEV_ATA)
                mask &= ~ATA_MASK_UDMA;
-       return ata_bmdma_mode_filter(adev, mask);
+       return mask;
 }
 
 
 
        /* Disk, UDMA */
        if (adev->class != ATA_DEV_ATA)
-               return ata_bmdma_mode_filter(adev, mask);
+               return mask;
 
        /* Actually do need to check */
        ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
                if (!strcmp(p, model_num))
                        mask &= ~(0xE0 << ATA_SHIFT_UDMA);
        }
-       return ata_bmdma_mode_filter(adev, mask);
+       return mask;
 }
 
 /**
 
                        mask &= ~ ATA_MASK_UDMA;
                }
        }
-       return ata_bmdma_mode_filter(dev, mask);
+       return mask;
 }
 
 /**
        struct via_port *vp;
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
-       int ret = ata_sff_port_start(ap);
+       int ret = ata_bmdma_port_start(ap);
        if (ret < 0)
                return ret;
 
 
 {
        struct device *dev = ap->host->dev;
        struct adma_port_priv *pp;
-       int rc;
 
-       rc = ata_port_start(ap);
-       if (rc)
-               return rc;
        adma_enter_reg_mode(ap);
        pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
        if (!pp)
 
 {
        struct device *dev = ap->host->dev;
        struct inic_port_priv *pp;
-       int rc;
 
        /* alloc and initialize private data */
        pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
        ap->private_data = pp;
 
        /* Alloc resources */
-       rc = ata_port_start(ap);
-       if (rc)
-               return rc;
-
        pp->pkt = dmam_alloc_coherent(dev, sizeof(struct inic_pkt),
                                      &pp->pkt_dma, GFP_KERNEL);
        if (!pp->pkt)
 
 
        .port_start             = mv_port_start,
        .port_stop              = mv_port_stop,
-
-       .mode_filter            = ATA_OP_NULL,  /* will be removed soon */
 };
 
 static struct ata_port_operations mv_iie_ops = {
 
        if (rc)
                return rc;
 
-       rc = ata_port_start(ap);
+       /* we might fallback to bmdma, allocate bmdma resources */
+       rc = ata_bmdma_port_start(ap);
        if (rc)
                return rc;
 
        struct nv_swncq_port_priv *pp;
        int rc;
 
-       rc = ata_port_start(ap);
+       /* we might fallback to bmdma, allocate bmdma resources */
+       rc = ata_bmdma_port_start(ap);
        if (rc)
                return rc;
 
 
        struct pdc_port_priv *pp;
        int rc;
 
-       rc = ata_port_start(ap);
+       /* we use the same prd table as bmdma, allocate it */
+       rc = ata_bmdma_port_start(ap);
        if (rc)
                return rc;
 
 
        void __iomem *mmio_base = qs_mmio_base(ap->host);
        void __iomem *chan = mmio_base + (ap->port_no * 0x4000);
        u64 addr;
-       int rc;
 
-       rc = ata_port_start(ap);
-       if (rc)
-               return rc;
        pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
        if (!pp)
                return -ENOMEM;
 
 {
        struct device *dev = ap->host->dev;
        struct pdc_port_priv *pp;
-       int rc;
-
-       rc = ata_port_start(ap);
-       if (rc)
-               return rc;
 
        pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
        if (!pp)
 
        if (rc)
                return rc;
 
-       rc = ata_pci_bmdma_init(host);
-       if (rc)
-               return rc;
+       ata_pci_bmdma_init(host);
 
        iomap = host->iomap;
 
 
 extern int ata_xfer_mode2shift(unsigned long xfer_mode);
 extern const char *ata_mode_string(unsigned long xfer_mask);
 extern unsigned long ata_id_xfermask(const u16 *id);
-extern int ata_port_start(struct ata_port *ap);
 extern int ata_std_qc_defer(struct ata_queued_cmd *qc);
 extern void ata_noop_qc_prep(struct ata_queued_cmd *qc);
 extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
 extern void ata_sff_drain_fifo(struct ata_queued_cmd *qc);
 extern void ata_sff_error_handler(struct ata_port *ap);
 extern void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc);
-extern int ata_sff_port_start(struct ata_port *ap);
-extern int ata_sff_port_start32(struct ata_port *ap);
 extern void ata_sff_std_ports(struct ata_ioports *ioaddr);
 #ifdef CONFIG_PCI
 extern int ata_pci_sff_init_host(struct ata_host *host);
                struct scsi_host_template *sht, void *host_priv, int hflags);
 #endif /* CONFIG_PCI */
 
-extern unsigned long ata_bmdma_mode_filter(struct ata_device *dev,
-                                          unsigned long xfer_mask);
 extern void ata_bmdma_setup(struct ata_queued_cmd *qc);
 extern void ata_bmdma_start(struct ata_queued_cmd *qc);
 extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
 extern u8 ata_bmdma_status(struct ata_port *ap);
+extern int ata_bmdma_port_start(struct ata_port *ap);
+extern int ata_bmdma_port_start32(struct ata_port *ap);
 
 #ifdef CONFIG_PCI
 extern int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev);
-extern int ata_pci_bmdma_init(struct ata_host *host);
+extern void ata_pci_bmdma_init(struct ata_host *host);
 #endif /* CONFIG_PCI */
 
 /**