aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-bmdma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libata-bmdma.c')
-rw-r--r--drivers/scsi/libata-bmdma.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index a89e44b21f4d..999725ca8d09 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -700,5 +700,41 @@ err_out:
700 return rc; 700 return rc;
701} 701}
702 702
703/**
704 * ata_pci_clear_simplex - attempt to kick device out of simplex
705 * @pdev: PCI device
706 *
707 * Some PCI ATA devices report simplex mode but in fact can be told to
708 * enter non simplex mode. This implements the neccessary logic to
709 * perform the task on such devices. Calling it on other devices will
710 * have -undefined- behaviour.
711 */
712
713int ata_pci_clear_simplex(struct pci_dev *pdev)
714{
715 unsigned long bmdma = pci_resource_start(pdev, 4);
716 u8 simplex;
717
718 if (bmdma == 0)
719 return -ENOENT;
720
721 simplex = inb(bmdma + 0x02);
722 outb(simplex & 0x60, bmdma + 0x02);
723 simplex = inb(bmdma + 0x02);
724 if (simplex & 0x80)
725 return -EOPNOTSUPP;
726 return 0;
727}
728
729unsigned long ata_pci_default_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long xfer_mask)
730{
731 /* Filter out DMA modes if the device has been configured by
732 the BIOS as PIO only */
733
734 if (ap->ioaddr.bmdma_addr == 0)
735 xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
736 return xfer_mask;
737}
738
703#endif /* CONFIG_PCI */ 739#endif /* CONFIG_PCI */
704 740