Make ide_rate_filter() also respect PIO/SWDMA/MWDMA mode masks. While at it,
make the udma_filter() method calls take precedence over using the mode masks.
---
This version doesn't use explicit UltraDMA masks, so converting them to the
ATA_UDMA* is left for another, global patch. This patch against the current
Linus' tree and unfortunately I was able to only compile test it since that
tree gives MODPOST warning and dies early on bootup.
drivers/ide/ide-dma.c | 7 +++--
drivers/ide/ide-lib.c | 65 +++++++++++++++++++++++++++++++++-----------------
2 files changed, 47 insertions(+), 25 deletions(-)
Index: linux-2.6/drivers/ide/ide-dma.c
===================================================================
--- linux-2.6.orig/drivers/ide/ide-dma.c
+++ linux-2.6/drivers/ide/ide-dma.c
@@ -664,10 +664,11 @@ static unsigned int ide_get_mode_mask(id
if ((id->field_valid & 4) == 0)
break;
- mask = id->dma_ultra & hwif->ultra_mask;
-
if (hwif->udma_filter)
- mask &= hwif->udma_filter(drive);
+ mask = hwif->udma_filter(drive);
+ else
+ mask = hwif->ultra_mask;
+ mask &= id->dma_ultra;
if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
mask &= 0x07;
Index: linux-2.6/drivers/ide/ide-lib.c
===================================================================
--- linux-2.6.orig/drivers/ide/ide-lib.c
+++ linux-2.6/drivers/ide/ide-lib.c
@@ -75,38 +75,59 @@ EXPORT_SYMBOL(ide_xfer_verbose);
*
* Given the available transfer modes this function returns
* the best available speed at or below the speed requested.
- *
- * FIXME: filter also PIO/SWDMA/MWDMA modes
*/
u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
{
-#ifdef CONFIG_BLK_DEV_IDEDMA
ide_hwif_t *hwif = drive->hwif;
- u8 mask = hwif->ultra_mask, mode = XFER_MW_DMA_2;
+ u8 mask, base = XFER_UDMA_0;
- if (hwif->udma_filter)
- mask = hwif->udma_filter(drive);
+ switch (speed & 0xf8) {
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ case XFER_UDMA_0:
+ mask = hwif->udma_filter ? hwif->udma_filter(drive) :
+ hwif->ultra_mask;
- /*
- * TODO: speed > XFER_UDMA_2 extra check is needed to avoid false
- * cable warning from eighty_ninty_three(), moving ide_rate_filter()
- * calls from ->speedproc to core code will make this hack go away
- */
- if (speed > XFER_UDMA_2) {
- if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
+ /*
+ * TODO: if speed > XFER_UDMA_2, an extra check is needed to
+ * avoid a false cable warning from eighty_ninty_three() --
+ * moving ide_rate_filter() calls from ->speedproc to core
+ * code will make this hack go away...
+ */
+ if (speed > XFER_UDMA_2 && (mask & 0x78) &&
+ eighty_ninty_three(drive) == 0)
mask &= 0x07;
- }
-
- if (mask)
- mode = fls(mask) - 1 + XFER_UDMA_0;
-// printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed);
-
- return min(speed, mode);
-#else /* !CONFIG_BLK_DEV_IDEDMA */
- return min(speed, (u8)XFER_PIO_4);
+ if (mask) {
+ base = XFER_UDMA_0;
+ break;
+ }
+ /* Fall thru */
+ case XFER_MW_DMA_0:
+ if (hwif->mwdma_mask) {
+ mask = hwif->mwdma_mask;
+ base = XFER_MW_DMA_0;
+ break;
+ }
+ /* Fall thru */
+ case XFER_SW_DMA_0:
+ if (hwif->swdma_mask) {
+ mask = hwif->swdma_mask;
+ base = XFER_SW_DMA_0;
+ break;
+ }
+ /* Fall thru */
#endif /* CONFIG_BLK_DEV_IDEDMA */
+ case XFER_PIO_0:
+ if (hwif->pio_mask) {
+ mask = hwif->pio_mask;
+ base = XFER_PIO_0;
+ break;
+ }
+ default:
+ BUG();
+ }
+ return min_t(u8, speed, base + fls(mask) - 1);
}
EXPORT_SYMBOL(ide_rate_filter);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]