aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-05-10 00:01:08 +0200
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-05-10 00:01:08 +0200
commit2d5eaa6dd744a641e75503232a01f52d0768884c (patch)
tree0736bd00ea3bd032d601d0a676c998cb043b877a
parent18137207236285989dfc0ee7f929b954199228f3 (diff)
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>
-rw-r--r--drivers/ide/arm/icside.c2
-rw-r--r--drivers/ide/cris/ide-cris.c2
-rw-r--r--drivers/ide/ide-dma.c74
-rw-r--r--drivers/ide/ide-iops.c2
-rw-r--r--drivers/ide/ide-lib.c125
-rw-r--r--drivers/ide/ide.c1
-rw-r--r--drivers/ide/pci/aec62xx.c32
-rw-r--r--drivers/ide/pci/alim15x3.c76
-rw-r--r--drivers/ide/pci/atiixp.c20
-rw-r--r--drivers/ide/pci/cmd64x.c65
-rw-r--r--drivers/ide/pci/cs5535.c20
-rw-r--r--drivers/ide/pci/hpt34x.c9
-rw-r--r--drivers/ide/pci/hpt366.c67
-rw-r--r--drivers/ide/pci/it8213.c20
-rw-r--r--drivers/ide/pci/it821x.c20
-rw-r--r--drivers/ide/pci/jmicron.c21
-rw-r--r--drivers/ide/pci/pdc202xx_new.c14
-rw-r--r--drivers/ide/pci/pdc202xx_old.c27
-rw-r--r--drivers/ide/pci/piix.c66
-rw-r--r--drivers/ide/pci/scc_pata.c21
-rw-r--r--drivers/ide/pci/serverworks.c31
-rw-r--r--drivers/ide/pci/siimage.c45
-rw-r--r--drivers/ide/pci/sis5513.c14
-rw-r--r--drivers/ide/pci/slc90e66.c13
-rw-r--r--drivers/ide/pci/tc86c001.c9
-rw-r--r--drivers/ide/pci/triflex.c4
-rw-r--r--include/linux/ide.h10
27 files changed, 236 insertions, 574 deletions
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index e2953fc1faf..f383ace2a08 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 5e8efc89255..9691d089fce 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 fd213088b06..f28fabb791f 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 3caa176b315..ed6128f6cd9 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 68719314df3..4557fc5a3ea 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 c06424fe647..73f752142f9 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 abe0b1bb55f..099539e8c7a 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 26c27d946c6..76643b626bd 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 2d48af32e3f..f7e80d6076d 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 610c45f7b4e..19f5ac1f866 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, &regU);
@@ -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 45f43efbf92..66a101e470d 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 924eaa3a570..473e1b33dbf 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 cf9d344d19f..de5ad9c35dc 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 424f00bb160..02b56cb7bb1 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 4e1254813ee..442f658c6ae 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