|
@@ -700,5 +700,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 */
|
|
|
|