aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-05-09 18:01:10 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-05-09 18:01:10 -0400
commit7f8f48af0861c38c28d4abd550102643e0ea9e6a (patch)
tree6ec47ace87afbd96cc1144d423854b09d9f21d75
parent7662d046df09e80680b77b68de896beab45e675e (diff)
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>
-rw-r--r--drivers/ide/ide-iops.c53
-rw-r--r--drivers/ide/ide-lib.c11
-rw-r--r--drivers/ide/pci/pdc202xx_new.c16
-rw-r--r--drivers/ide/pci/pdc202xx_old.c20
-rw-r--r--include/linux/ide.h1
5 files changed, 40 insertions, 61 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);
571 */ 571 */
572u8 eighty_ninty_three (ide_drive_t *drive) 572u8 eighty_ninty_three (ide_drive_t *drive)
573{ 573{
574 if(HWIF(drive)->udma_four == 0) 574 ide_hwif_t *hwif = drive->hwif;
575 return 0; 575 struct hd_driveid *id = drive->id;
576
577 if (hwif->udma_four == 0)
578 goto no_80w;
576 579
577 /* Check for SATA but only if we are ATA5 or higher */ 580 /* Check for SATA but only if we are ATA5 or higher */
578 if (drive->id->hw_config == 0 && (drive->id->major_rev_num & 0x7FE0)) 581 if (id->hw_config == 0 && (id->major_rev_num & 0x7FE0))
579 return 1; 582 return 1;
580 if (!(drive->id->hw_config & 0x6000)) 583
581 return 0;
582#ifndef CONFIG_IDEDMA_IVB
583 if(!(drive->id->hw_config & 0x4000))
584 return 0;
585#endif /* CONFIG_IDEDMA_IVB */
586 /* 584 /*
587 * FIXME: 585 * FIXME:
588 * - change master/slave IDENTIFY order 586 * - change master/slave IDENTIFY order
589 * - force bit13 (80c cable present) check 587 * - force bit13 (80c cable present) check
590 * (unless the slave device is pre-ATA3) 588 * (unless the slave device is pre-ATA3)
591 */ 589 */
592 return 1; 590#ifndef CONFIG_IDEDMA_IVB
591 if (id->hw_config & 0x4000)
592#else
593 if (id->hw_config & 0x6000)
594#endif
595 return 1;
596
597no_80w:
598 if (drive->udma33_warned == 1)
599 return 0;
600
601 printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, "
602 "limiting max speed to UDMA33\n",
603 drive->name, hwif->udma_four ? "drive" : "host");
604
605 drive->udma33_warned = 1;
606
607 return 0;
593} 608}
594 609
595int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) 610int 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)
597 if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && 612 if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
598 (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) && 613 (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
599 (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) { 614 (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
600#ifndef CONFIG_IDEDMA_IVB 615 if (eighty_ninty_three(drive) == 0) {
601 if ((drive->id->hw_config & 0x6000) == 0) { 616 printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
602#else /* !CONFIG_IDEDMA_IVB */ 617 "be set\n", drive->name);
603 if (((drive->id->hw_config & 0x2000) == 0) ||
604 ((drive->id->hw_config & 0x4000) == 0)) {
605#endif /* CONFIG_IDEDMA_IVB */
606 printk("%s: Speed warnings UDMA 3/4/5 is not "
607 "functional.\n", drive->name);
608 return 1;
609 }
610 if (!HWIF(drive)->udma_four) {
611 printk("%s: Speed warnings UDMA 3/4/5 is not "
612 "functional.\n",
613 HWIF(drive)->name);
614 return 1; 618 return 1;
615 } 619 }
616 } 620 }
621
617 return 0; 622 return 0;
618} 623}
619 624
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 4557fc5a3ea3..3be3c69383f2 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -88,8 +88,15 @@ u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
88 if (hwif->udma_filter) 88 if (hwif->udma_filter)
89 mask = hwif->udma_filter(drive); 89 mask = hwif->udma_filter(drive);
90 90
91 if ((mask & 0x78) && (eighty_ninty_three(drive) == 0)) 91 /*
92 mask &= 0x07; 92 * TODO: speed > XFER_UDMA_2 extra check is needed to avoid false
93 * cable warning from eighty_ninty_three(), moving ide_rate_filter()
94 * calls from ->speedproc to core code will make this hack go away
95 */
96 if (speed > XFER_UDMA_2) {
97 if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
98 mask &= 0x07;
99 }
93 100
94 if (mask) 101 if (mask)
95 mode = fls(mask) - 1 + XFER_UDMA_0; 102 mode = fls(mask) - 1 + XFER_UDMA_0;
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 772ca4007de4..65b1e124edf7 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -37,8 +37,6 @@
37#include <asm/pci-bridge.h> 37#include <asm/pci-bridge.h>
38#endif 38#endif
39 39
40#define PDC202_DEBUG_CABLE 0
41
42#undef DEBUG 40#undef DEBUG
43 41
44#ifdef DEBUG 42#ifdef DEBUG
@@ -234,17 +232,8 @@ static int config_chipset_for_dma(ide_drive_t *drive)
234{ 232{
235 struct hd_driveid *id = drive->id; 233 struct hd_driveid *id = drive->id;
236 ide_hwif_t *hwif = HWIF(drive); 234 ide_hwif_t *hwif = HWIF(drive);
237 u8 ultra_66 = (id->dma_ultra & 0x0078) ? 1 : 0;
238 u8 cable = pdcnew_cable_detect(hwif);
239 u8 speed; 235 u8 speed;
240 236
241 if (ultra_66 && cable) {
242 printk(KERN_WARNING "Warning: %s channel "
243 "requires an 80-pin cable for operation.\n",
244 hwif->channel ? "Secondary" : "Primary");
245 printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name);
246 }
247
248 if (id->capability & 4) { 237 if (id->capability & 4) {
249 /* 238 /*
250 * Set IORDY_EN & PREFETCH_EN (this seems to have 239 * Set IORDY_EN & PREFETCH_EN (this seems to have
@@ -547,11 +536,6 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
547 if (!noautodma) 536 if (!noautodma)
548 hwif->autodma = 1; 537 hwif->autodma = 1;
549 hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; 538 hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
550
551#if PDC202_DEBUG_CABLE
552 printk(KERN_DEBUG "%s: %s-pin cable\n",
553 hwif->name, hwif->udma_four ? "80" : "40");
554#endif /* PDC202_DEBUG_CABLE */
555} 539}
556 540
557static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d) 541static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index 207a6191fac7..7146fe3f6ba7 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -46,7 +46,6 @@
46#include <asm/io.h> 46#include <asm/io.h>
47#include <asm/irq.h> 47#include <asm/irq.h>
48 48
49#define PDC202_DEBUG_CABLE 0
50#define PDC202XX_DEBUG_DRIVE_INFO 0 49#define PDC202XX_DEBUG_DRIVE_INFO 0
51 50
52static const char *pdc_quirk_drives[] = { 51static const char *pdc_quirk_drives[] = {
@@ -238,20 +237,7 @@ static int config_chipset_for_dma (ide_drive_t *drive)
238 u32 drive_conf = 0; 237 u32 drive_conf = 0;
239 u8 drive_pci = 0x60 + (drive->dn << 2); 238 u8 drive_pci = 0x60 + (drive->dn << 2);
240 u8 test1 = 0, test2 = 0, speed = -1; 239 u8 test1 = 0, test2 = 0, speed = -1;
241 u8 AP = 0, cable = 0; 240 u8 AP = 0;
242
243 u8 ultra_66 = ((id->dma_ultra & 0x0010) ||
244 (id->dma_ultra & 0x0008)) ? 1 : 0;
245
246 if (dev->device != PCI_DEVICE_ID_PROMISE_20246)
247 cable = pdc202xx_old_cable_detect(hwif);
248 else
249 ultra_66 = 0;
250
251 if (ultra_66 && cable) {
252 printk(KERN_WARNING "Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary");
253 printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name);
254 }
255 241
256 if (dev->device != PCI_DEVICE_ID_PROMISE_20246) 242 if (dev->device != PCI_DEVICE_ID_PROMISE_20246)
257 pdc_old_disable_66MHz_clock(drive->hwif); 243 pdc_old_disable_66MHz_clock(drive->hwif);
@@ -477,10 +463,6 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
477 if (!noautodma) 463 if (!noautodma)
478 hwif->autodma = 1; 464 hwif->autodma = 1;
479 hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; 465 hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
480#if PDC202_DEBUG_CABLE
481 printk(KERN_DEBUG "%s: %s-pin cable\n",
482 hwif->name, hwif->udma_four ? "80" : "40");
483#endif /* PDC202_DEBUG_CABLE */
484} 466}
485 467
486static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase) 468static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 477b8c6be727..ca924b295c2e 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -605,6 +605,7 @@ typedef struct ide_drive_s {
605 unsigned scsi : 1; /* 0=default, 1=ide-scsi emulation */ 605 unsigned scsi : 1; /* 0=default, 1=ide-scsi emulation */
606 unsigned sleeping : 1; /* 1=sleeping & sleep field valid */ 606 unsigned sleeping : 1; /* 1=sleeping & sleep field valid */
607 unsigned post_reset : 1; 607 unsigned post_reset : 1;
608 unsigned udma33_warned : 1;
608 609
609 u8 addressing; /* 0=28-bit, 1=48-bit, 2=48-bit doing 28-bit */ 610 u8 addressing; /* 0=28-bit, 1=48-bit, 2=48-bit doing 28-bit */
610 u8 quirk_list; /* considered quirky, set for a specific host */ 611 u8 quirk_list; /* considered quirky, set for a specific host */