diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-05-09 18:01:10 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-05-09 18:01:10 -0400 |
commit | 7f8f48af0861c38c28d4abd550102643e0ea9e6a (patch) | |
tree | 6ec47ace87afbd96cc1144d423854b09d9f21d75 | |
parent | 7662d046df09e80680b77b68de896beab45e675e (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.c | 53 | ||||
-rw-r--r-- | drivers/ide/ide-lib.c | 11 | ||||
-rw-r--r-- | drivers/ide/pci/pdc202xx_new.c | 16 | ||||
-rw-r--r-- | drivers/ide/pci/pdc202xx_old.c | 20 | ||||
-rw-r--r-- | include/linux/ide.h | 1 |
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 | */ |
572 | u8 eighty_ninty_three (ide_drive_t *drive) | 572 | u8 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 | |||
597 | no_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 | ||
595 | int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) | 610 | 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) | |||
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 | ||
557 | static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d) | 541 | static 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 | ||
52 | static const char *pdc_quirk_drives[] = { | 51 | static 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 | ||
486 | static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase) | 468 | static 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 */ |