diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-05-10 00:01:08 +0200 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-05-10 00:01:08 +0200 |
commit | 2d5eaa6dd744a641e75503232a01f52d0768884c (patch) | |
tree | 0736bd00ea3bd032d601d0a676c998cb043b877a | |
parent | ide: fix UDMA/MWDMA/SWDMA masks (v3) (diff) | |
download | linux-2d5eaa6dd744a641e75503232a01f52d0768884c.tar.xz linux-2d5eaa6dd744a641e75503232a01f52d0768884c.zip |
ide: rework the code for selecting the best DMA transfer mode (v3)
Depends on the "ide: fix UDMA/MWDMA/SWDMA masks" patch.
* add ide_hwif_t.udma_filter hook for filtering UDMA mask
(use it in alim15x3, hpt366, siimage and serverworks drivers)
* add ide_max_dma_mode() for finding best DMA mode for the device
(loosely based on some older libata-core.c code)
* convert ide_dma_speed() users to use ide_max_dma_mode()
* make ide_rate_filter() take "ide_drive_t *drive" as an argument instead
of "u8 mode" and teach it to how to use UDMA mask to do filtering
* use ide_rate_filter() in hpt366 driver
* remove no longer needed ide_dma_speed() and *_ratemask()
* unexport eighty_ninty_three()
v2:
* rename ->filter_udma_mask to ->udma_filter
[ Suggested by Sergei Shtylyov <sshtylyov@ru.mvista.com>. ]
v3:
* updated for scc_pata driver (fixes XFER_UDMA_6 filtering for user-space
originated transfer mode change requests when 100MHz clock is used)
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
27 files changed, 236 insertions, 574 deletions
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index e2953fc1fafb..f383ace2a087 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -342,7 +342,7 @@ static int icside_dma_check(ide_drive_t *drive) * Enable DMA on any drive that has multiword DMA */ if (id->field_valid & 2) { - xfer_mode = ide_dma_speed(drive, 0); + xfer_mode = ide_max_dma_mode(drive); goto out; } diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index 5e8efc89255a..9691d089fce8 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c @@ -1004,7 +1004,7 @@ static int cris_ide_build_dmatable (ide_drive_t *drive) static int cris_config_drive_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, 1); + u8 speed = ide_max_dma_mode(drive); if (!speed) return 0; 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) EXPORT_SYMBOL_GPL(ide_use_dma); +static const u8 xfer_mode_bases[] = { + XFER_UDMA_0, + XFER_MW_DMA_0, + XFER_SW_DMA_0, +}; + +static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base) +{ + struct hd_driveid *id = drive->id; + ide_hwif_t *hwif = drive->hwif; + unsigned int mask = 0; + + switch(base) { + case XFER_UDMA_0: + if ((id->field_valid & 4) == 0) + break; + + mask = id->dma_ultra & hwif->ultra_mask; + + if (hwif->udma_filter) + mask &= hwif->udma_filter(drive); + + if ((mask & 0x78) && (eighty_ninty_three(drive) == 0)) + mask &= 0x07; + break; + case XFER_MW_DMA_0: + mask = id->dma_mword & hwif->mwdma_mask; + break; + case XFER_SW_DMA_0: + mask = id->dma_1word & hwif->swdma_mask; + break; + default: + BUG(); + break; + } + + return mask; +} + +/** + * ide_max_dma_mode - compute DMA speed + * @drive: IDE device + * + * Checks the drive capabilities and returns the speed to use + * for the DMA transfer. Returns 0 if the drive is incapable + * of DMA transfers. + */ + +u8 ide_max_dma_mode(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + unsigned int mask; + int x, i; + u8 mode = 0; + + if (drive->media != ide_disk && hwif->atapi_dma == 0) + return 0; + + for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) { + mask = ide_get_mode_mask(drive, xfer_mode_bases[i]); + x = fls(mask) - 1; + if (x >= 0) { + mode = xfer_mode_bases[i] + x; + break; + } + } + + printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode); + + return mode; +} + +EXPORT_SYMBOL_GPL(ide_max_dma_mode); + void ide_dma_verbose(ide_drive_t *drive) { struct hd_driveid *id = drive->id; diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 3caa176b3155..ed6128f6cd98 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -592,8 +592,6 @@ u8 eighty_ninty_three (ide_drive_t *drive) return 1; } -EXPORT_SYMBOL(eighty_ninty_three); - int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) { if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 68719314df3f..4557fc5a3ea3 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -69,123 +69,34 @@ char *ide_xfer_verbose (u8 xfer_rate) EXPORT_SYMBOL(ide_xfer_verbose); /** - * ide_dma_speed - compute DMA speed - * @drive: drive - * @mode: modes available - * - * Checks the drive capabilities and returns the speed to use - * for the DMA transfer. Returns 0 if the drive is incapable - * of DMA transfers. - */ - -u8 ide_dma_speed(ide_drive_t *drive, u8 mode) -{ - struct hd_driveid *id = drive->id; - ide_hwif_t *hwif = HWIF(drive); - u8 ultra_mask, mwdma_mask, swdma_mask; - u8 speed = 0; - - if (drive->media != ide_disk && hwif->atapi_dma == 0) - return 0; - - /* Capable of UltraDMA modes? */ - ultra_mask = id->dma_ultra & hwif->ultra_mask; - - if (!(id->field_valid & 4)) - mode = 0; /* fallback to MW/SW DMA if no UltraDMA */ - - switch (mode) { - case 4: - if (ultra_mask & 0x40) { - speed = XFER_UDMA_6; - break; - } - case 3: - if (ultra_mask & 0x20) { - speed = XFER_UDMA_5; - break; - } - case 2: - if (ultra_mask & 0x10) { - speed = XFER_UDMA_4; - break; - } - if (ultra_mask & 0x08) { - speed = XFER_UDMA_3; - break; - } - case 1: - if (ultra_mask & 0x04) { - speed = XFER_UDMA_2; - break; - } - if (ultra_mask & 0x02) { - speed = XFER_UDMA_1; - break; - } - if (ultra_mask & 0x01) { - speed = XFER_UDMA_0; - break; - } - case 0: - mwdma_mask = id->dma_mword & hwif->mwdma_mask; - - if (mwdma_mask & 0x04) { - speed = XFER_MW_DMA_2; - break; - } - if (mwdma_mask & 0x02) { - speed = XFER_MW_DMA_1; - break; - } - if (mwdma_mask & 0x01) { - speed = XFER_MW_DMA_0; - break; - } - - swdma_mask = id->dma_1word & hwif->swdma_mask; - - if (swdma_mask & 0x04) { - speed = XFER_SW_DMA_2; - break; - } - if (swdma_mask & 0x02) { - speed = XFER_SW_DMA_1; - break; - } - if (swdma_mask & 0x01) { - speed = XFER_SW_DMA_0; - break; - } - } - - return speed; -} -EXPORT_SYMBOL(ide_dma_speed); - - -/** - * ide_rate_filter - return best speed for mode - * @mode: modes available + * ide_rate_filter - filter transfer mode + * @drive: IDE device * @speed: desired speed * - * Given the available DMA/UDMA mode this function returns + * 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 (u8 mode, u8 speed) +u8 ide_rate_filter(ide_drive_t *drive, u8 speed) { #ifdef CONFIG_BLK_DEV_IDEDMA - static u8 speed_max[] = { - XFER_MW_DMA_2, XFER_UDMA_2, XFER_UDMA_4, - XFER_UDMA_5, XFER_UDMA_6 - }; + ide_hwif_t *hwif = drive->hwif; + u8 mask = hwif->ultra_mask, mode = XFER_MW_DMA_2; + + if (hwif->udma_filter) + mask = hwif->udma_filter(drive); + + if ((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); - /* So that we remember to update this if new modes appear */ - BUG_ON(mode > 4); - return min(speed, speed_max[mode]); + return min(speed, mode); #else /* !CONFIG_BLK_DEV_IDEDMA */ return min(speed, (u8)XFER_PIO_4); #endif /* CONFIG_BLK_DEV_IDEDMA */ diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index c06424fe647b..73f752142f9e 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -477,6 +477,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->tuneproc = tmp_hwif->tuneproc; hwif->speedproc = tmp_hwif->speedproc; + hwif->udma_filter = tmp_hwif->udma_filter; hwif->selectproc = tmp_hwif->selectproc; hwif->reset_poll = tmp_hwif->reset_poll; hwif->pre_reset = tmp_hwif->pre_reset; diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index abe0b1bb55ff..099539e8c7a3 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -87,38 +87,12 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr return chipset_table->ultra_settings; } -static u8 aec62xx_ratemask (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 mode; - - switch(hwif->pci_dev->device) { - case PCI_DEVICE_ID_ARTOP_ATP865: - case PCI_DEVICE_ID_ARTOP_ATP865R: - mode = (inb(hwif->channel ? - hwif->mate->dma_status : - hwif->dma_status) & 0x10) ? 4 : 3; - break; - case PCI_DEVICE_ID_ARTOP_ATP860: - case PCI_DEVICE_ID_ARTOP_ATP860R: - mode = 2; - break; - case PCI_DEVICE_ID_ARTOP_ATP850UF: - default: - return 1; - } - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - static int aec6210_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u16 d_conf = 0; - u8 speed = ide_rate_filter(aec62xx_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); u8 ultra = 0, ultra_conf = 0; u8 tmp0 = 0, tmp1 = 0, tmp2 = 0; unsigned long flags; @@ -145,7 +119,7 @@ static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(aec62xx_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); u8 unit = (drive->select.b.unit & 0x01); u8 tmp1 = 0, tmp2 = 0; u8 ultra = 0, drive_conf = 0, ultra_conf = 0; @@ -183,7 +157,7 @@ static int aec62xx_tune_chipset (ide_drive_t *drive, u8 speed) static int config_chipset_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, aec62xx_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!(speed)) return 0; diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 26c27d946c67..76643b626bdd 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -378,74 +378,31 @@ static void ali15x3_tune_drive (ide_drive_t *drive, u8 pio) } /** - * ali15x3_can_ultra - check for ultra DMA support - * @drive: drive to do the check + * ali_udma_filter - compute UDMA mask + * @drive: IDE device * - * Check the drive and controller revisions. Return 0 if UDMA is - * not available, or 1 if UDMA can be used. The actual rules for - * the ALi are + * Return available UDMA modes. + * + * The actual rules for the ALi are: * No UDMA on revisions <= 0x20 * Disk only for revisions < 0xC2 * Not WDC drives for revisions < 0xC2 * * FIXME: WDC ifdef needs to die */ - -static u8 ali15x3_can_ultra (ide_drive_t *drive) -{ -#ifndef CONFIG_WDC_ALI15X3 - struct hd_driveid *id = drive->id; -#endif /* CONFIG_WDC_ALI15X3 */ - - if (m5229_revision <= 0x20) { - return 0; - } else if ((m5229_revision < 0xC2) && -#ifndef CONFIG_WDC_ALI15X3 - ((chip_is_1543c_e && strstr(id->model, "WDC ")) || - (drive->media!=ide_disk))) { -#else /* CONFIG_WDC_ALI15X3 */ - (drive->media!=ide_disk)) { -#endif /* CONFIG_WDC_ALI15X3 */ - return 0; - } else { - return 1; - } -} -/** - * ali15x3_ratemask - generate DMA mode list - * @drive: drive to compute against - * - * Generate a list of the available DMA modes for the drive. - * FIXME: this function contains lots of bogus masking we can dump - * - * Return the highest available mode (UDMA33, UDMA66, UDMA100,..) - */ - -static u8 ali15x3_ratemask (ide_drive_t *drive) +static u8 ali_udma_filter(ide_drive_t *drive) { - u8 mode = 0, can_ultra = ali15x3_can_ultra(drive); - - if (m5229_revision > 0xC4 && can_ultra) { - mode = 4; - } else if (m5229_revision == 0xC4 && can_ultra) { - mode = 3; - } else if (m5229_revision >= 0xC2 && can_ultra) { - mode = 2; - } else if (can_ultra) { - return 1; - } else { - return 0; + if (m5229_revision > 0x20 && m5229_revision < 0xC2) { + if (drive->media != ide_disk) + return 0; +#ifndef CONFIG_WDC_ALI15X3 + if (chip_is_1543c_e && strstr(drive->id->model, "WDC ")) + return 0; +#endif } - /* - * If the drive sees no suitable cable then UDMA 33 - * is the highest permitted mode - */ - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; + return drive->hwif->ultra_mask; } /** @@ -461,7 +418,7 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(ali15x3_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); u8 speed1 = speed; u8 unit = (drive->select.b.unit & 0x01); u8 tmpbyte = 0x00; @@ -511,7 +468,7 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed) static int config_chipset_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, ali15x3_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!(speed)) return 0; @@ -771,6 +728,7 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) hwif->autodma = 0; hwif->tuneproc = &ali15x3_tune_drive; hwif->speedproc = &ali15x3_tune_chipset; + hwif->udma_filter = &ali_udma_filter; /* don't use LBA48 DMA on ALi devices before rev 0xC5 */ hwif->no_lba48_dma = (m5229_revision <= 0xC4) ? 1 : 0; diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 2d48af32e3f4..f7e80d6076d7 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -49,22 +49,6 @@ static int save_mdma_mode[4]; static DEFINE_SPINLOCK(atiixp_lock); /** - * atiixp_ratemask - compute rate mask for ATIIXP IDE - * @drive: IDE drive to compute for - * - * Returns the available modes for the ATIIXP IDE controller. - */ - -static u8 atiixp_ratemask(ide_drive_t *drive) -{ - u8 mode = 3; - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/** * atiixp_dma_2_pio - return the PIO mode matching DMA * @xfer_rate: transfer speed * @@ -189,7 +173,7 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed) u16 tmp16; u8 speed, pio; - speed = ide_rate_filter(atiixp_ratemask(drive), xferspeed); + speed = ide_rate_filter(drive, xferspeed); spin_lock_irqsave(&atiixp_lock, flags); @@ -233,7 +217,7 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed) static int atiixp_config_drive_for_dma(ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, atiixp_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!speed) return 0; diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 610c45f7b4e2..19f5ac1f866c 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -292,55 +292,6 @@ static void cmd64x_tune_drive (ide_drive_t *drive, u8 pio) (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); } -static u8 cmd64x_ratemask (ide_drive_t *drive) -{ - struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 mode = 0; - - switch(dev->device) { - case PCI_DEVICE_ID_CMD_649: - mode = 3; - break; - case PCI_DEVICE_ID_CMD_648: - mode = 2; - break; - case PCI_DEVICE_ID_CMD_643: - return 0; - - case PCI_DEVICE_ID_CMD_646: - { - unsigned int class_rev = 0; - pci_read_config_dword(dev, - PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - /* - * UltraDMA only supported on PCI646U and PCI646U2, which - * correspond to revisions 0x03, 0x05 and 0x07 respectively. - * Actually, although the CMD tech support people won't - * tell me the details, the 0x03 revision cannot support - * UDMA correctly without hardware modifications, and even - * then it only works with Quantum disks due to some - * hold time assumptions in the 646U part which are fixed - * in the 646U2. - * - * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. - */ - switch(class_rev) { - case 0x07: - case 0x05: - return 1; - case 0x03: - case 0x01: - default: - return 0; - } - } - } - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed) { ide_hwif_t *hwif = HWIF(drive); @@ -348,7 +299,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed) u8 unit = drive->dn & 0x01; u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0; - speed = ide_rate_filter(cmd64x_ratemask(drive), speed); + speed = ide_rate_filter(drive, speed); if (speed >= XFER_SW_DMA_0) { (void) pci_read_config_byte(dev, pciU, ®U); @@ -403,7 +354,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed) static int config_chipset_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, cmd64x_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!speed) return 0; @@ -646,6 +597,18 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) hwif->ultra_mask = hwif->cds->udma_mask; + /* + * UltraDMA only supported on PCI646U and PCI646U2, which + * correspond to revisions 0x03, 0x05 and 0x07 respectively. + * Actually, although the CMD tech support people won't + * tell me the details, the 0x03 revision cannot support + * UDMA correctly without hardware modifications, and even + * then it only works with Quantum disks due to some + * hold time assumptions in the 646U part which are fixed + * in the 646U2. + * + * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. + */ if (dev->device == PCI_DEVICE_ID_CMD_646 && class_rev < 5) hwif->ultra_mask = 0x00; diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 45f43efbf92c..66a101e470d0 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -127,20 +127,6 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed) } } -static u8 cs5535_ratemask(ide_drive_t *drive) -{ - /* eighty93 will return 1 if it's 80core and capable of - exceeding udma2, 0 otherwise. we need ratemask to set - the max speed and if we can > udma2 then we return 2 - which selects speed_max as udma4 which is the 5535's max - speed, and 1 selects udma2 which is the max for 40c */ - if (!eighty_ninty_three(drive)) - return 1; - - return 2; -} - - /**** * cs5535_set_drive - Configure the drive to the new speed * @drive: Drive to set up @@ -151,7 +137,7 @@ static u8 cs5535_ratemask(ide_drive_t *drive) */ static int cs5535_set_drive(ide_drive_t *drive, u8 speed) { - speed = ide_rate_filter(cs5535_ratemask(drive), speed); + speed = ide_rate_filter(drive, speed); ide_config_drive_speed(drive, speed); cs5535_set_speed(drive, speed); @@ -180,9 +166,7 @@ static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed) static int cs5535_config_drive_for_dma(ide_drive_t *drive) { - u8 speed; - - speed = ide_dma_speed(drive, cs5535_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); /* If no DMA speed was available then let dma_check hit pio */ if (!speed) { diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index 924eaa3a5708..473e1b33dbf7 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c @@ -43,15 +43,10 @@ #define HPT343_DEBUG_DRIVE_INFO 0 -static u8 hpt34x_ratemask (ide_drive_t *drive) -{ - return 1; -} - static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed) { struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 speed = ide_rate_filter(hpt34x_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0; u8 hi_speed, lo_speed; @@ -98,7 +93,7 @@ static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio) static int config_chipset_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, hpt34x_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!(speed)) return 0; diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index cf9d344d19f8..de5ad9c35dc6 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -514,43 +514,31 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list) return 0; } -static u8 hpt3xx_ratemask(ide_drive_t *drive) -{ - struct hpt_info *info = pci_get_drvdata(HWIF(drive)->pci_dev); - u8 mode = info->max_mode; - - if (!eighty_ninty_three(drive) && mode) - mode = min(mode, (u8)1); - return mode; -} - /* * Note for the future; the SATA hpt37x we must set * either PIO or UDMA modes 0,4,5 */ - -static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed) + +static u8 hpt3xx_udma_filter(ide_drive_t *drive) { struct hpt_info *info = pci_get_drvdata(HWIF(drive)->pci_dev); u8 chip_type = info->chip_type; - u8 mode = hpt3xx_ratemask(drive); - - if (drive->media != ide_disk) - return min(speed, (u8)XFER_PIO_4); + u8 mode = info->max_mode; + u8 mask; switch (mode) { case 0x04: - speed = min_t(u8, speed, XFER_UDMA_6); + mask = 0x7f; break; case 0x03: - speed = min_t(u8, speed, XFER_UDMA_5); + mask = 0x3f; if (chip_type >= HPT374) break; if (!check_in_drive_list(drive, bad_ata100_5)) goto check_bad_ata33; /* fall thru */ case 0x02: - speed = min_t(u8, speed, XFER_UDMA_4); + mask = 0x1f; /* * CHECK ME, Does this need to be changed to HPT374 ?? @@ -561,13 +549,13 @@ static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed) !check_in_drive_list(drive, bad_ata66_4)) goto check_bad_ata33; - speed = min_t(u8, speed, XFER_UDMA_3); + mask = 0x0f; if (HPT366_ALLOW_ATA66_3 && !check_in_drive_list(drive, bad_ata66_3)) goto check_bad_ata33; /* fall thru */ case 0x01: - speed = min_t(u8, speed, XFER_UDMA_2); + mask = 0x07; check_bad_ata33: if (chip_type >= HPT370A) @@ -577,10 +565,10 @@ static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed) /* fall thru */ case 0x00: default: - speed = min_t(u8, speed, XFER_MW_DMA_2); + mask = 0x00; break; } - return speed; + return mask; } static u32 get_speed_setting(u8 speed, struct hpt_info *info) @@ -608,12 +596,19 @@ static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; struct hpt_info *info = pci_get_drvdata(dev); - u8 speed = hpt3xx_ratefilter(drive, xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); u8 itr_addr = drive->dn ? 0x44 : 0x40; - u32 itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 : - (speed < XFER_UDMA_0 ? 0xc0070000 : 0xc03800ff); - u32 new_itr = get_speed_setting(speed, info); u32 old_itr = 0; + u32 itr_mask, new_itr; + + /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */ + if (drive->media != ide_disk) + speed = min_t(u8, speed, XFER_PIO_4); + + itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 : + (speed < XFER_UDMA_0 ? 0xc0070000 : 0xc03800ff); + + new_itr = get_speed_setting(speed, info); /* * Disable on-chip PIO FIFO/buffer (and PIO MST mode as well) @@ -633,12 +628,19 @@ static int hpt37x_tune_chipset(ide_drive_t *drive, u8 xferspeed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; struct hpt_info *info = pci_get_drvdata(dev); - u8 speed = hpt3xx_ratefilter(drive, xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); u8 itr_addr = 0x40 + (drive->dn * 4); - u32 itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 : - (speed < XFER_UDMA_0 ? 0xc03c0000 : 0xc1c001ff); - u32 new_itr = get_speed_setting(speed, info); u32 old_itr = 0; + u32 itr_mask, new_itr; + + /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */ + if (drive->media != ide_disk) + speed = min_t(u8, speed, XFER_PIO_4); + + itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 : + (speed < XFER_UDMA_0 ? 0xc03c0000 : 0xc1c001ff); + + new_itr = get_speed_setting(speed, info); pci_read_config_dword(dev, itr_addr, &old_itr); new_itr = (new_itr & ~itr_mask) | (old_itr & itr_mask); @@ -676,7 +678,7 @@ static void hpt3xx_tune_drive(ide_drive_t *drive, u8 pio) */ static int config_chipset_for_dma(ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, hpt3xx_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!speed) return 0; @@ -1271,6 +1273,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) hwif->intrproc = &hpt3xx_intrproc; hwif->maskproc = &hpt3xx_maskproc; hwif->busproc = &hpt3xx_busproc; + hwif->udma_filter = &hpt3xx_udma_filter; /* * HPT3xxN chips have some complications: diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c index 424f00bb160d..02b56cb7bb1b 100644 --- a/drivers/ide/pci/it8213.c +++ b/drivers/ide/pci/it8213.c @@ -17,22 +17,6 @@ #include <asm/io.h> -/* - * it8213_ratemask - Compute available modes - * @drive: IDE drive - * - * Compute the available speeds for the devices on the interface. This - * is all modes to ATA133 clipped by drive cable setup. - */ - -static u8 it8213_ratemask (ide_drive_t *drive) -{ - u8 mode = 4; - if (!eighty_ninty_three(drive)) - mode = min_t(u8, mode, 1); - return mode; -} - /** * it8213_dma_2_pio - return the PIO mode matching DMA * @xfer_rate: transfer speed @@ -145,7 +129,7 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 maslave = 0x40; - u8 speed = ide_rate_filter(it8213_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); int a_speed = 3 << (drive->dn * 4); int u_flag = 1 << drive->dn; int v_flag = 0x01 << drive->dn; @@ -222,7 +206,7 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed) static int config_chipset_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, it8213_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!speed) return 0; diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 4e1254813ee0..442f658c6ae7 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c @@ -229,22 +229,6 @@ static void it821x_clock_strategy(ide_drive_t *drive) } /** - * it821x_ratemask - Compute available modes - * @drive: IDE drive - * - * Compute the available speeds for the devices on the interface. This - * is all modes to ATA133 clipped by drive cable setup. - */ - -static u8 it821x_ratemask (ide_drive_t *drive) -{ - u8 mode = 4; - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/** * it821x_tunepio - tune a drive * @drive: drive to tune * @pio: the desired PIO mode @@ -438,7 +422,7 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed) ide_hwif_t *hwif = drive->hwif; struct it821x_dev *itdev = ide_get_hwifdata(hwif); - u8 speed = ide_rate_filter(it821x_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); switch (speed) { case XFER_PIO_4: @@ -488,7 +472,7 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed) static int config_chipset_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, it821x_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (speed == 0) return 0; diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index be4fc96c29e0..dbb3c199cba9 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c @@ -22,22 +22,6 @@ typedef enum { } port_type; /** - * jmicron_ratemask - Compute available modes - * @drive: IDE drive - * - * Compute the available speeds for the devices on the interface. This - * is all modes to ATA133 clipped by drive cable setup. - */ - -static u8 jmicron_ratemask(ide_drive_t *drive) -{ - u8 mode = 4; - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/** * ata66_jmicron - Cable check * @hwif: IDE port * @@ -129,8 +113,7 @@ static void config_jmicron_chipset_for_pio (ide_drive_t *drive, byte set_speed) static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed) { - - u8 speed = ide_rate_filter(jmicron_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); return ide_config_drive_speed(drive, speed); } @@ -145,7 +128,7 @@ static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed) static int config_chipset_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, jmicron_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!speed) return 0; diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index a23853445af9..772ca4007de4 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -82,16 +82,6 @@ static u8 max_dma_rate(struct pci_dev *pdev) return mode; } -static u8 pdcnew_ratemask(ide_drive_t *drive) -{ - u8 mode = max_dma_rate(HWIF(drive)->pci_dev); - - if (!eighty_ninty_three(drive)) - mode = min_t(u8, mode, 1); - - return mode; -} - /** * get_indexed_reg - Get indexed register * @hwif: for the port address @@ -164,7 +154,7 @@ static int pdcnew_tune_chipset(ide_drive_t *drive, u8 speed) u8 adj = (drive->dn & 1) ? 0x08 : 0x00; int err; - speed = ide_rate_filter(pdcnew_ratemask(drive), speed); + speed = ide_rate_filter(drive, speed); /* * Issue SETFEATURES_XFER to the drive first. PDC202xx hardware will @@ -267,7 +257,7 @@ static int config_chipset_for_dma(ide_drive_t *drive) set_indexed_reg(hwif, 0x13 + adj, tmp | 0x03); } - speed = ide_dma_speed(drive, pdcnew_ratemask(drive)); + speed = ide_max_dma_mode(drive); if (!speed) return 0; diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index d7a38067fb34..207a6191fac7 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -101,35 +101,12 @@ static const char *pdc_quirk_drives[] = { #define MC1 0x02 /* DMA"C" timing */ #define MC0 0x01 /* DMA"C" timing */ -static u8 pdc202xx_ratemask (ide_drive_t *drive) -{ - u8 mode; - - switch(HWIF(drive)->pci_dev->device) { - case PCI_DEVICE_ID_PROMISE_20267: - case PCI_DEVICE_ID_PROMISE_20265: - mode = 3; - break; - case PCI_DEVICE_ID_PROMISE_20263: - case PCI_DEVICE_ID_PROMISE_20262: - mode = 2; - break; - case PCI_DEVICE_ID_PROMISE_20246: - return 1; - default: - return 0; - } - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 drive_pci = 0x60 + (drive->dn << 2); - u8 speed = ide_rate_filter(pdc202xx_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); u32 drive_conf; u8 AP, BP, CP, DP; @@ -308,7 +285,7 @@ chipset_is_set: if (drive->media == ide_disk) /* PREFETCH_EN */ pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); - speed = ide_dma_speed(drive, pdc202xx_ratemask(drive)); + speed = ide_max_dma_mode(drive); if (!(speed)) { /* restore original pci-config space */ diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 17ea44edb4eb..84d3938a430a 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -106,68 +106,6 @@ static int no_piix_dma; /** - * piix_ratemask - compute rate mask for PIIX IDE - * @drive: IDE drive to compute for - * - * Returns the available modes for the PIIX IDE controller. - */ - -static u8 piix_ratemask (ide_drive_t *drive) -{ - struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 mode; - - switch(dev->device) { - case PCI_DEVICE_ID_INTEL_82801EB_1: - mode = 3; - break; - /* UDMA 100 capable */ - case PCI_DEVICE_ID_INTEL_82801BA_8: - case PCI_DEVICE_ID_INTEL_82801BA_9: - case PCI_DEVICE_ID_INTEL_82801CA_10: - case PCI_DEVICE_ID_INTEL_82801CA_11: - case PCI_DEVICE_ID_INTEL_82801E_11: - case PCI_DEVICE_ID_INTEL_82801DB_1: - case PCI_DEVICE_ID_INTEL_82801DB_10: - case PCI_DEVICE_ID_INTEL_82801DB_11: - case PCI_DEVICE_ID_INTEL_82801EB_11: - case PCI_DEVICE_ID_INTEL_ESB_2: - case PCI_DEVICE_ID_INTEL_ICH6_19: - case PCI_DEVICE_ID_INTEL_ICH7_21: - case PCI_DEVICE_ID_INTEL_ESB2_18: - case PCI_DEVICE_ID_INTEL_ICH8_6: - mode = 3; - break; - /* UDMA 66 capable */ - case PCI_DEVICE_ID_INTEL_82801AA_1: - case PCI_DEVICE_ID_INTEL_82372FB_1: - mode = 2; - break; - /* UDMA 33 capable */ - case PCI_DEVICE_ID_INTEL_82371AB: - case PCI_DEVICE_ID_INTEL_82443MX_1: - case PCI_DEVICE_ID_INTEL_82451NX: - case PCI_DEVICE_ID_INTEL_82801AB_1: - return 1; - /* Non UDMA capable (MWDMA2) */ - case PCI_DEVICE_ID_INTEL_82371SB_1: - case PCI_DEVICE_ID_INTEL_82371FB_1: - case PCI_DEVICE_ID_INTEL_82371FB_0: - case PCI_DEVICE_ID_INTEL_82371MX: - default: - return 0; - } - - /* - * If we are UDMA66 capable fall back to UDMA33 - * if the drive cannot see an 80pin cable. - */ - if (!eighty_ninty_three(drive)) - mode = min_t(u8, mode, 1); - return mode; -} - -/** * piix_dma_2_pio - return the PIO mode matching DMA * @xfer_rate: transfer speed * @@ -301,7 +239,7 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 maslave = hwif->channel ? 0x42 : 0x40; - u8 speed = ide_rate_filter(piix_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); int a_speed = 3 << (drive->dn * 4); int u_flag = 1 << drive->dn; int v_flag = 0x01 << drive->dn; @@ -376,7 +314,7 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) static int piix_config_drive_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, piix_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); /* * If no DMA speed was available or the chipset has DMA bugs diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index f84bf791f72e..cbf936325355 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -190,23 +190,6 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count) } /** - * scc_ratemask - Compute available modes - * @drive: IDE drive - * - * Compute the available speeds for the devices on the interface. - * Enforce UDMA33 as a limit if there is no 80pin cable present. - */ - -static u8 scc_ratemask(ide_drive_t *drive) -{ - u8 mode = 4; - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/** * scc_tuneproc - tune a drive PIO mode * @drive: drive to tune * @mode_wanted: the target operating mode @@ -273,7 +256,7 @@ static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted) static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) { ide_hwif_t *hwif = HWIF(drive); - u8 speed = ide_rate_filter(scc_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); struct scc_ports *ports = ide_get_hwifdata(hwif); unsigned long ctl_base = ports->ctl; unsigned long cckctrl_port = ctl_base + 0xff0; @@ -347,7 +330,7 @@ static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) static int scc_config_chipset_for_dma(ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, scc_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!speed) return 0; diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index dbcd37a0c652..2fa6d92d16cc 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -65,16 +65,16 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list) return 0; } -static u8 svwks_ratemask (ide_drive_t *drive) +static u8 svwks_udma_filter(ide_drive_t *drive) { struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 mode = 0; + u8 mask = 0; if (!svwks_revision) pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision); if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) - return 2; + return 0x1f; if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { u32 reg = 0; if (isa_dev) @@ -86,25 +86,31 @@ static u8 svwks_ratemask (ide_drive_t *drive) if(drive->media == ide_disk) return 0; /* Check the OSB4 DMA33 enable bit */ - return ((reg & 0x00004000) == 0x00004000) ? 1 : 0; + return ((reg & 0x00004000) == 0x00004000) ? 0x07 : 0; } else if (svwks_revision < SVWKS_CSB5_REVISION_NEW) { - return 1; + return 0x07; } else if (svwks_revision >= SVWKS_CSB5_REVISION_NEW) { - u8 btr = 0; + u8 btr = 0, mode; pci_read_config_byte(dev, 0x5A, &btr); mode = btr & 0x3; - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); + /* If someone decides to do UDMA133 on CSB5 the same issue will bite so be inclusive */ if (mode > 2 && check_in_drive_lists(drive, svwks_bad_ata100)) mode = 2; + + switch(mode) { + case 2: mask = 0x1f; break; + case 1: mask = 0x07; break; + default: mask = 0x00; break; + } } if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) && (!(PCI_FUNC(dev->devfn) & 1))) - mode = 2; - return mode; + mask = 0x1f; + + return mask; } static u8 svwks_csb_check (struct pci_dev *dev) @@ -141,7 +147,7 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) if (xferspeed == 255) /* PIO auto-tuning */ speed = XFER_PIO_0 + pio; else - speed = ide_rate_filter(svwks_ratemask(drive), xferspeed); + speed = ide_rate_filter(drive, xferspeed); /* If we are about to put a disk into UDMA mode we screwed up. Our code assumes we never _ever_ do this on an OSB4 */ @@ -304,7 +310,7 @@ static void svwks_tune_drive (ide_drive_t *drive, u8 pio) static int config_chipset_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, svwks_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!(speed)) speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); @@ -500,6 +506,7 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) hwif->tuneproc = &svwks_tune_drive; hwif->speedproc = &svwks_tune_chipset; + hwif->udma_filter = &svwks_udma_filter; hwif->atapi_dma = 1; diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index c0188de3cc66..5314ec913724 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -122,45 +122,41 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) } /** - * siimage_ratemask - Compute available modes - * @drive: IDE drive + * sil_udma_filter - compute UDMA mask + * @drive: IDE device + * + * Compute the available UDMA speeds for the device on the interface. * - * Compute the available speeds for the devices on the interface. * For the CMD680 this depends on the clocking mode (scsc), for the - * SI3312 SATA controller life is a bit simpler. Enforce UDMA33 - * as a limit if there is no 80pin cable present. + * SI3112 SATA controller life is a bit simpler. */ - -static byte siimage_ratemask (ide_drive_t *drive) + +static u8 sil_udma_filter(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - u8 mode = 0, scsc = 0; + ide_hwif_t *hwif = drive->hwif; unsigned long base = (unsigned long) hwif->hwif_data; + u8 mask = 0, scsc = 0; if (hwif->mmio) scsc = hwif->INB(base + 0x4A); else pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc); - if(is_sata(hwif)) - { - if(strstr(drive->id->model, "Maxtor")) - return 3; - return 4; + if (is_sata(hwif)) { + mask = strstr(drive->id->model, "Maxtor") ? 0x3f : 0x7f; + goto out; } - + if ((scsc & 0x30) == 0x10) /* 133 */ - mode = 4; + mask = 0x7f; else if ((scsc & 0x30) == 0x20) /* 2xPCI */ - mode = 4; + mask = 0x7f; else if ((scsc & 0x30) == 0x00) /* 100 */ - mode = 3; + mask = 0x3f; else /* Disabled ? */ BUG(); - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; +out: + return mask; } /** @@ -306,7 +302,7 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) ide_hwif_t *hwif = HWIF(drive); u16 ultra = 0, multi = 0; u8 mode = 0, unit = drive->select.b.unit; - u8 speed = ide_rate_filter(siimage_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); unsigned long base = (unsigned long)hwif->hwif_data; u8 scsc = 0, addr_mask = ((hwif->channel) ? ((hwif->mmio) ? 0xF4 : 0x84) : @@ -389,7 +385,7 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) static int config_chipset_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, siimage_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!speed) return 0; @@ -989,6 +985,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) hwif->tuneproc = &siimage_tuneproc; hwif->reset_poll = &siimage_reset_poll; hwif->pre_reset = &siimage_pre_reset; + hwif->udma_filter = &sil_udma_filter; if(is_sata(hwif)) { static int first = 1; diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 6fe4ecb6c06c..83c80ed73e99 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -428,16 +428,6 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count) } #endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */ -static u8 sis5513_ratemask (ide_drive_t *drive) -{ - u8 rates[] = { 0, 0, 1, 2, 3, 3, 4, 4 }; - u8 mode = rates[chipset_family]; - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - /* * Configuration functions */ @@ -563,7 +553,7 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) u8 drive_pci, reg, speed; u32 regdw; - speed = ide_rate_filter(sis5513_ratemask(drive), xferspeed); + speed = ide_rate_filter(drive, xferspeed); /* See config_art_rwp_pio for drive pci config registers */ drive_pci = 0x40; @@ -653,7 +643,7 @@ static void sis5513_tune_drive (ide_drive_t *drive, u8 pio) */ static int config_chipset_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, sis5513_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); #ifdef DEBUG printk("SIS5513: config_chipset_for_dma, drive %d, ultra %x\n", diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 852ccb36da1d..9e95a5cbf984 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -21,15 +21,6 @@ #include <asm/io.h> -static u8 slc90e66_ratemask (ide_drive_t *drive) -{ - u8 mode = 2; - - if (!eighty_ninty_three(drive)) - mode = min_t(u8, mode, 1); - return mode; -} - static u8 slc90e66_dma_2_pio (u8 xfer_rate) { switch(xfer_rate) { case XFER_UDMA_4: @@ -122,7 +113,7 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 maslave = hwif->channel ? 0x42 : 0x40; - u8 speed = ide_rate_filter(slc90e66_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); int sitre = 0, a_speed = 7 << (drive->dn * 4); int u_speed = 0, u_flag = 1 << drive->dn; u16 reg4042, reg44, reg48, reg4a; @@ -171,7 +162,7 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) static int slc90e66_config_drive_for_dma (ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!speed) return 0; diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c index 0b6d81d6ce48..168f035caa3f 100644 --- a/drivers/ide/pci/tc86c001.c +++ b/drivers/ide/pci/tc86c001.c @@ -13,18 +13,13 @@ #include <linux/pci.h> #include <linux/ide.h> -static inline u8 tc86c001_ratemask(ide_drive_t *drive) -{ - return eighty_ninty_three(drive) ? 2 : 1; -} - static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed) { ide_hwif_t *hwif = HWIF(drive); unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00); u16 mode, scr = hwif->INW(scr_port); - speed = ide_rate_filter(tc86c001_ratemask(drive), speed); + speed = ide_rate_filter(drive, speed); switch (speed) { case XFER_UDMA_4: mode = 0x00c0; break; @@ -174,7 +169,7 @@ static int tc86c001_busproc(ide_drive_t *drive, int state) static int config_chipset_for_dma(ide_drive_t *drive) { - u8 speed = ide_dma_speed(drive, tc86c001_ratemask(drive)); + u8 speed = ide_max_dma_mode(drive); if (!speed) return 0; diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index 5e06179c3469..8a877235b949 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -48,7 +48,7 @@ static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed) u16 timing = 0; u32 triflex_timings = 0; u8 unit = (drive->select.b.unit & 0x01); - u8 speed = ide_rate_filter(0, xferspeed); + u8 speed = ide_rate_filter(drive, xferspeed); pci_read_config_dword(dev, channel_offset, &triflex_timings); @@ -102,7 +102,7 @@ static void triflex_tune_drive(ide_drive_t *drive, u8 pio) static int triflex_config_drive_for_dma(ide_drive_t *drive) { - int speed = ide_dma_speed(drive, 0); /* No ultra speeds */ + u8 speed = ide_max_dma_mode(drive); if (!speed) return 0; diff --git a/include/linux/ide.h b/include/linux/ide.h index c9375c863584..23ab4dc05009 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -717,11 +717,8 @@ typedef struct hwif_s { int (*quirkproc)(ide_drive_t *); /* driver soft-power interface */ int (*busproc)(ide_drive_t *, int); -// /* host rate limiter */ -// u8 (*ratemask)(ide_drive_t *); -// /* device rate limiter */ -// u8 (*ratefilter)(ide_drive_t *, u8); #endif + u8 (*udma_filter)(ide_drive_t *); void (*ata_input_data)(ide_drive_t *, void *, u32); void (*ata_output_data)(ide_drive_t *, void *, u32); @@ -1279,6 +1276,7 @@ int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *); int __ide_dma_bad_drive(ide_drive_t *); int __ide_dma_good_drive(ide_drive_t *); int ide_use_dma(ide_drive_t *); +u8 ide_max_dma_mode(ide_drive_t *); void ide_dma_off(ide_drive_t *); void ide_dma_verbose(ide_drive_t *); int ide_set_dma(ide_drive_t *); @@ -1305,6 +1303,7 @@ extern int __ide_dma_timeout(ide_drive_t *); #else static inline int ide_use_dma(ide_drive_t *drive) { return 0; } +static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; } static inline void ide_dma_off(ide_drive_t *drive) { ; } static inline void ide_dma_verbose(ide_drive_t *drive) { ; } static inline int ide_set_dma(ide_drive_t *drive) { return 1; } @@ -1349,8 +1348,7 @@ static inline void ide_set_hwifdata (ide_hwif_t * hwif, void *data) } /* ide-lib.c */ -extern u8 ide_dma_speed(ide_drive_t *drive, u8 mode); -extern u8 ide_rate_filter(u8 mode, u8 speed); +u8 ide_rate_filter(ide_drive_t *, u8); extern int ide_dma_enable(ide_drive_t *drive); extern char *ide_xfer_verbose(u8 xfer_rate); extern void ide_toggle_bounce(ide_drive_t *drive, int on); |