diff options
Diffstat (limited to 'drivers/ide/ide-dma.c')
-rw-r--r-- | drivers/ide/ide-dma.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index fd213088b06b..f28fabb791fe 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -705,6 +705,80 @@ int ide_use_dma(ide_drive_t *drive) | |||
705 | 705 | ||
706 | EXPORT_SYMBOL_GPL(ide_use_dma); | 706 | EXPORT_SYMBOL_GPL(ide_use_dma); |
707 | 707 | ||
708 | static const u8 xfer_mode_bases[] = { | ||
709 | XFER_UDMA_0, | ||
710 | XFER_MW_DMA_0, | ||
711 | XFER_SW_DMA_0, | ||
712 | }; | ||
713 | |||
714 | static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base) | ||
715 | { | ||
716 | struct hd_driveid *id = drive->id; | ||
717 | ide_hwif_t *hwif = drive->hwif; | ||
718 | unsigned int mask = 0; | ||
719 | |||
720 | switch(base) { | ||
721 | case XFER_UDMA_0: | ||
722 | if ((id->field_valid & 4) == 0) | ||
723 | break; | ||
724 | |||
725 | mask = id->dma_ultra & hwif->ultra_mask; | ||
726 | |||
727 | if (hwif->udma_filter) | ||
728 | mask &= hwif->udma_filter(drive); | ||
729 | |||
730 | if ((mask & 0x78) && (eighty_ninty_three(drive) == 0)) | ||
731 | mask &= 0x07; | ||
732 | break; | ||
733 | case XFER_MW_DMA_0: | ||
734 | mask = id->dma_mword & hwif->mwdma_mask; | ||
735 | break; | ||
736 | case XFER_SW_DMA_0: | ||
737 | mask = id->dma_1word & hwif->swdma_mask; | ||
738 | break; | ||
739 | default: | ||
740 | BUG(); | ||
741 | break; | ||
742 | } | ||
743 | |||
744 | return mask; | ||
745 | } | ||
746 | |||
747 | /** | ||
748 | * ide_max_dma_mode - compute DMA speed | ||
749 | * @drive: IDE device | ||
750 | * | ||
751 | * Checks the drive capabilities and returns the speed to use | ||
752 | * for the DMA transfer. Returns 0 if the drive is incapable | ||
753 | * of DMA transfers. | ||
754 | */ | ||
755 | |||
756 | u8 ide_max_dma_mode(ide_drive_t *drive) | ||
757 | { | ||
758 | ide_hwif_t *hwif = drive->hwif; | ||
759 | unsigned int mask; | ||
760 | int x, i; | ||
761 | u8 mode = 0; | ||
762 | |||
763 | if (drive->media != ide_disk && hwif->atapi_dma == 0) | ||
764 | return 0; | ||
765 | |||
766 | for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) { | ||
767 | mask = ide_get_mode_mask(drive, xfer_mode_bases[i]); | ||
768 | x = fls(mask) - 1; | ||
769 | if (x >= 0) { | ||
770 | mode = xfer_mode_bases[i] + x; | ||
771 | break; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode); | ||
776 | |||
777 | return mode; | ||
778 | } | ||
779 | |||
780 | EXPORT_SYMBOL_GPL(ide_max_dma_mode); | ||
781 | |||
708 | void ide_dma_verbose(ide_drive_t *drive) | 782 | void ide_dma_verbose(ide_drive_t *drive) |
709 | { | 783 | { |
710 | struct hd_driveid *id = drive->id; | 784 | struct hd_driveid *id = drive->id; |