diff options
Diffstat (limited to 'drivers/scsi/libata-bmdma.c')
-rw-r--r-- | drivers/scsi/libata-bmdma.c | 36 |
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 | |||
713 | int 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 | |||
729 | unsigned 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 | ||