summaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-iops.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz2007-05-10 00:01:10 +0200
committerBartlomiej Zolnierkiewicz2007-05-10 00:01:10 +0200
commit7f8f48af0861c38c28d4abd550102643e0ea9e6a (patch)
tree6ec47ace87afbd96cc1144d423854b09d9f21d75 /drivers/ide/ide-iops.c
parentide: move IDE settings handling to ide-proc.c (diff)
downloadkernel-qcow2-linux-7f8f48af0861c38c28d4abd550102643e0ea9e6a.tar.gz
kernel-qcow2-linux-7f8f48af0861c38c28d4abd550102643e0ea9e6a.tar.xz
kernel-qcow2-linux-7f8f48af0861c38c28d4abd550102643e0ea9e6a.zip
ide: cable detection fixes (take 2)
Tejun's recent eighty_ninty_three() fix has inspired me to do more thorough review of the cable detection code... * print user-friendly warning about limiting the maximum transfer speed to UDMA33 (and the reason behind it) when 80-wire cable is not detected, also while at it cleanup eighty_ninty_three() a bit * use eighty_ninty_three() in ide_ata66_check(), this actually fixes 3 bugs: - bit 14 (word 93 validity check) == 1 && bit 13 (80-wire cable test) == 1 were used as 80-wire cable present test for CONFIG_IDEDMA_IVB=n case (please see FIXME comment in eighty_ninty_three() for more details) - CONFIG_IDEDMA_IVB=y/n cases were interchanged - check for SATA devices was missing * remove private cable warnings from pdc_202xx{old,new} drivers now that core code provides this functionality (plus, in pdc202xx_new case the test could give false warnings for ATAPI devices because pdc202xx_new driver doesn't even support ATAPI DMA) Cc: Tejun Heo <htejun@gmail.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r--drivers/ide/ide-iops.c53
1 files changed, 29 insertions, 24 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index ed6128f6cd98..f0be5f665a0e 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -571,25 +571,40 @@ EXPORT_SYMBOL(ide_wait_stat);
*/
u8 eighty_ninty_three (ide_drive_t *drive)
{
- if(HWIF(drive)->udma_four == 0)
- return 0;
+ ide_hwif_t *hwif = drive->hwif;
+ struct hd_driveid *id = drive->id;
+
+ if (hwif->udma_four == 0)
+ goto no_80w;
/* Check for SATA but only if we are ATA5 or higher */
- if (drive->id->hw_config == 0 && (drive->id->major_rev_num & 0x7FE0))
+ if (id->hw_config == 0 && (id->major_rev_num & 0x7FE0))
return 1;
- if (!(drive->id->hw_config & 0x6000))
- return 0;
-#ifndef CONFIG_IDEDMA_IVB
- if(!(drive->id->hw_config & 0x4000))
- return 0;
-#endif /* CONFIG_IDEDMA_IVB */
+
/*
* FIXME:
* - change master/slave IDENTIFY order
* - force bit13 (80c cable present) check
* (unless the slave device is pre-ATA3)
*/
- return 1;
+#ifndef CONFIG_IDEDMA_IVB
+ if (id->hw_config & 0x4000)
+#else
+ if (id->hw_config & 0x6000)
+#endif
+ return 1;
+
+no_80w:
+ if (drive->udma33_warned == 1)
+ return 0;
+
+ printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, "
+ "limiting max speed to UDMA33\n",
+ drive->name, hwif->udma_four ? "drive" : "host");
+
+ drive->udma33_warned = 1;
+
+ return 0;
}
int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
@@ -597,23 +612,13 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
(args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
(args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
-#ifndef CONFIG_IDEDMA_IVB
- if ((drive->id->hw_config & 0x6000) == 0) {
-#else /* !CONFIG_IDEDMA_IVB */
- if (((drive->id->hw_config & 0x2000) == 0) ||
- ((drive->id->hw_config & 0x4000) == 0)) {
-#endif /* CONFIG_IDEDMA_IVB */
- printk("%s: Speed warnings UDMA 3/4/5 is not "
- "functional.\n", drive->name);
- return 1;
- }
- if (!HWIF(drive)->udma_four) {
- printk("%s: Speed warnings UDMA 3/4/5 is not "
- "functional.\n",
- HWIF(drive)->name);
+ if (eighty_ninty_three(drive) == 0) {
+ printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
+ "be set\n", drive->name);
return 1;
}
}
+
return 0;
}