[PATCH] i2c: scx200_acb fix and speed up the poll loop
[powerpc.git] / drivers / scsi / libata-bmdma.c
index a93336a..96b4d21 100644 (file)
@@ -214,6 +214,8 @@ static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile
  *     Issues MMIO write to ATA command register, with proper
  *     synchronization with interrupt handler / other threads.
  *
+ *     FIXME: missing write posting for 400nS delay enforcement
+ *
  *     LOCKING:
  *     spin_lock_irqsave(host_set lock)
  */
@@ -648,6 +650,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                goto err_out_regions;
        }
 
+       /* FIXME: If we get no DMA mask we should fall back to PIO */
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
                goto err_out_regions;
@@ -699,5 +702,41 @@ err_out:
        return rc;
 }
 
+/**
+ *     ata_pci_clear_simplex   -       attempt to kick device out of simplex
+ *     @pdev: PCI device
+ *
+ *     Some PCI ATA devices report simplex mode but in fact can be told to
+ *     enter non simplex mode. This implements the neccessary logic to 
+ *     perform the task on such devices. Calling it on other devices will
+ *     have -undefined- behaviour.
+ */
+
+int ata_pci_clear_simplex(struct pci_dev *pdev)
+{
+       unsigned long bmdma = pci_resource_start(pdev, 4);
+       u8 simplex;
+
+       if (bmdma == 0)
+               return -ENOENT;
+
+       simplex = inb(bmdma + 0x02);
+       outb(simplex & 0x60, bmdma + 0x02);
+       simplex = inb(bmdma + 0x02);
+       if (simplex & 0x80)
+               return -EOPNOTSUPP;
+       return 0;
+}
+
+unsigned long ata_pci_default_filter(const struct ata_port *ap, 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 (ap->ioaddr.bmdma_addr == 0)
+               xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
+       return xfer_mask;
+}
+
 #endif /* CONFIG_PCI */