aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-08-20 16:42:56 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-08-20 16:42:56 -0400
commita5b7e70d787f528386eda025d3e38f545017f241 (patch)
tree8cef80801bebf9b9d87ae97420b92f15ad3472f3
parent59785c8fe23ca2f432bc41ef473a8933ab435812 (diff)
ide: add cable detection for early UDMA66 devices (take 3)
* Move ide_in_drive_list() from ide-dma.c to ide-iops.c. * Add ivb_list[] table for listening early UDMA66 devices which don't conform to ATA4 standard wrt cable detection (bit14 is zero, only bit13 is valid) and use only device side cable detection for them since host side cable detection may be unreliable. * Add model "QUANTUM FIREBALLlct10 05" with firwmare "A03.0900" to the list (from Craig's bugreport). v2: * Improve kernel message basing on suggestion from Sergei. v3: * Don't print kernel message when no device side cable detection is done, plus some minor fixes. (Noticed by Sergei) Thanks to Craig for testing this patch. Cc: Craig Block <chblock3@yahoo.com> Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/ide/ide-dma.c19
-rw-r--r--drivers/ide/ide-iops.c39
-rw-r--r--include/linux/ide.h3
3 files changed, 38 insertions, 23 deletions
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 865a2740a6e3..ff644a5e12cd 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -135,25 +135,6 @@ static const struct drive_list_entry drive_blacklist [] = {
135}; 135};
136 136
137/** 137/**
138 * ide_in_drive_list - look for drive in black/white list
139 * @id: drive identifier
140 * @drive_table: list to inspect
141 *
142 * Look for a drive in the blacklist and the whitelist tables
143 * Returns 1 if the drive is found in the table.
144 */
145
146int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
147{
148 for ( ; drive_table->id_model ; drive_table++)
149 if ((!strcmp(drive_table->id_model, id->model)) &&
150 (!drive_table->id_firmware ||
151 strstr(id->fw_rev, drive_table->id_firmware)))
152 return 1;
153 return 0;
154}
155
156/**
157 * ide_dma_intr - IDE DMA interrupt handler 138 * ide_dma_intr - IDE DMA interrupt handler
158 * @drive: the drive the interrupt is for 139 * @drive: the drive the interrupt is for
159 * 140 *
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 92578b6832e9..fe2a69fed72b 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -565,6 +565,34 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b
565 565
566EXPORT_SYMBOL(ide_wait_stat); 566EXPORT_SYMBOL(ide_wait_stat);
567 567
568/**
569 * ide_in_drive_list - look for drive in black/white list
570 * @id: drive identifier
571 * @drive_table: list to inspect
572 *
573 * Look for a drive in the blacklist and the whitelist tables
574 * Returns 1 if the drive is found in the table.
575 */
576
577int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
578{
579 for ( ; drive_table->id_model; drive_table++)
580 if ((!strcmp(drive_table->id_model, id->model)) &&
581 (!drive_table->id_firmware ||
582 strstr(id->fw_rev, drive_table->id_firmware)))
583 return 1;
584 return 0;
585}
586
587/*
588 * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid.
589 * We list them here and depend on the device side cable detection for them.
590 */
591static const struct drive_list_entry ivb_list[] = {
592 { "QUANTUM FIREBALLlct10 05" , "A03.0900" },
593 { NULL , NULL }
594};
595
568/* 596/*
569 * All hosts that use the 80c ribbon must use! 597 * All hosts that use the 80c ribbon must use!
570 * The name is derived from upper byte of word 93 and the 80c ribbon. 598 * The name is derived from upper byte of word 93 and the 80c ribbon.
@@ -573,11 +601,16 @@ u8 eighty_ninty_three (ide_drive_t *drive)
573{ 601{
574 ide_hwif_t *hwif = drive->hwif; 602 ide_hwif_t *hwif = drive->hwif;
575 struct hd_driveid *id = drive->id; 603 struct hd_driveid *id = drive->id;
604 int ivb = ide_in_drive_list(id, ivb_list);
576 605
577 if (hwif->cbl == ATA_CBL_PATA40_SHORT) 606 if (hwif->cbl == ATA_CBL_PATA40_SHORT)
578 return 1; 607 return 1;
579 608
580 if (hwif->cbl != ATA_CBL_PATA80) 609 if (ivb)
610 printk(KERN_DEBUG "%s: skipping word 93 validity check\n",
611 drive->name);
612
613 if (hwif->cbl != ATA_CBL_PATA80 && !ivb)
581 goto no_80w; 614 goto no_80w;
582 615
583 /* Check for SATA but only if we are ATA5 or higher */ 616 /* Check for SATA but only if we are ATA5 or higher */
@@ -587,11 +620,11 @@ u8 eighty_ninty_three (ide_drive_t *drive)
587 /* 620 /*
588 * FIXME: 621 * FIXME:
589 * - change master/slave IDENTIFY order 622 * - change master/slave IDENTIFY order
590 * - force bit13 (80c cable present) check 623 * - force bit13 (80c cable present) check also for !ivb devices
591 * (unless the slave device is pre-ATA3) 624 * (unless the slave device is pre-ATA3)
592 */ 625 */
593#ifndef CONFIG_IDEDMA_IVB 626#ifndef CONFIG_IDEDMA_IVB
594 if (id->hw_config & 0x4000) 627 if ((id->hw_config & 0x4000) || (ivb && (id->hw_config & 0x2000)))
595#else 628#else
596 if (id->hw_config & 0x6000) 629 if (id->hw_config & 0x6000)
597#endif 630#endif
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 7e15e0870290..c792b4fd1588 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1285,13 +1285,14 @@ void ide_init_sg_cmd(ide_drive_t *, struct request *);
1285#define BAD_DMA_DRIVE 0 1285#define BAD_DMA_DRIVE 0
1286#define GOOD_DMA_DRIVE 1 1286#define GOOD_DMA_DRIVE 1
1287 1287
1288#ifdef CONFIG_BLK_DEV_IDEDMA
1289struct drive_list_entry { 1288struct drive_list_entry {
1290 const char *id_model; 1289 const char *id_model;
1291 const char *id_firmware; 1290 const char *id_firmware;
1292}; 1291};
1293 1292
1294int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *); 1293int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *);
1294
1295#ifdef CONFIG_BLK_DEV_IDEDMA
1295int __ide_dma_bad_drive(ide_drive_t *); 1296int __ide_dma_bad_drive(ide_drive_t *);
1296int __ide_dma_good_drive(ide_drive_t *); 1297int __ide_dma_good_drive(ide_drive_t *);
1297u8 ide_max_dma_mode(ide_drive_t *); 1298u8 ide_max_dma_mode(ide_drive_t *);