aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-06-08 09:14:29 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-06-08 09:14:29 -0400
commit0380dad45e4f5a606025cc4df2a2cd26af08796b (patch)
treec135a4a5527ce98bb3473342061f3990feef7d42
parent1abb8a8b841354e7a09ba2009376f0a6368b5cec (diff)
it821x: RAID mode fixes
The DMA support for RAID mode broke after: commit 71ef51cc1756d1c56b57c70e7cc27a3559c81ee6 Author: Jens Axboe <axboe@suse.de> Date:   Fri Jul 28 09:02:17 2006 +0200     [PATCH] it821x: fix ide dma setup bug     Only enable dma for a valid speed setting.     Signed-off-by: Jens Axboe <axboe@suse.de> commit 0a8348d08677ad77ee353f96eb8745c693a05a13 Author: Jens Axboe <axboe@suse.de> Date:   Fri Jul 28 08:58:26 2006 +0200     [PATCH] ide: if the id fields looks screwy, disable DMA     It's the safer choice. Originally due to a bug in itx821x, but a     generally sound thing to do.     Signed-off-by: Jens Axboe <axboe@suse.de> However it worked by pure luck before Jens' fixes: bogus ide_dma_enable() usage in it821x driver combined with loosy check in ide_dma_verbose() allowed the hardware to operate in DMA mode. When these problems were fixed the DMA support broke... The source root for the regression turned out to be that the it821x.c code was clearing too much of id->field_valid. The IDE core code was using the original value of id->field_valid to do the tuning but later DMA got disabled in ide_dma_verbose() because of the incorrect id->field_valid fixup. Fix it. While at it: * Do fixup() after probing the drives but before tuning them (which is also OK w.r.t. ide_undecoded_slave() fixup). This change fixes device IDENTIFY data to be consistent before/after the tuning and allows us to remove extra re-tuning of drives from it821x_fixups(). * Fake MWDMA0 enabled/supported bits in IDENTIFY data if the device has DMA capable bit set (this is just to tell the IDE core that DMA is supported since it821x firmware takes care of DMA mode programming). * Don't touch timing registers and don't program transfer modes on devices et all when in RAID mode - depend solely on firmware to do the tuning (as suggested by Alan Cox and done in libata pata_it821x driver). Thanks for testing the patch goes out to Thomas Kuther. Cc: Thomas Kuther <gimpel@sonnenkinder.org> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: Jens Axboe <axboe@suse.de> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/ide/ide-probe.c12
-rw-r--r--drivers/ide/pci/it821x.c34
2 files changed, 24 insertions, 22 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 3cebed77f55d..41bfa4d21ab6 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -717,7 +717,7 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
717 * This routine only knows how to look for drive units 0 and 1 717 * This routine only knows how to look for drive units 0 and 1
718 * on an interface, so any setting of MAX_DRIVES > 2 won't work here. 718 * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
719 */ 719 */
720static void probe_hwif(ide_hwif_t *hwif) 720static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
721{ 721{
722 unsigned int unit; 722 unsigned int unit;
723 unsigned long flags; 723 unsigned long flags;
@@ -820,6 +820,9 @@ static void probe_hwif(ide_hwif_t *hwif)
820 return; 820 return;
821 } 821 }
822 822
823 if (fixup)
824 fixup(hwif);
825
823 for (unit = 0; unit < MAX_DRIVES; ++unit) { 826 for (unit = 0; unit < MAX_DRIVES; ++unit) {
824 ide_drive_t *drive = &hwif->drives[unit]; 827 ide_drive_t *drive = &hwif->drives[unit];
825 828
@@ -874,10 +877,7 @@ static int hwif_init(ide_hwif_t *hwif);
874 877
875int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)) 878int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
876{ 879{
877 probe_hwif(hwif); 880 probe_hwif(hwif, fixup);
878
879 if (fixup)
880 fixup(hwif);
881 881
882 if (!hwif_init(hwif)) { 882 if (!hwif_init(hwif)) {
883 printk(KERN_INFO "%s: failed to initialize IDE interface\n", 883 printk(KERN_INFO "%s: failed to initialize IDE interface\n",
@@ -1404,7 +1404,7 @@ int ideprobe_init (void)
1404 1404
1405 for (index = 0; index < MAX_HWIFS; ++index) 1405 for (index = 0; index < MAX_HWIFS; ++index)
1406 if (probe[index]) 1406 if (probe[index])
1407 probe_hwif(&ide_hwifs[index]); 1407 probe_hwif(&ide_hwifs[index], NULL);
1408 for (index = 0; index < MAX_HWIFS; ++index) 1408 for (index = 0; index < MAX_HWIFS; ++index)
1409 if (probe[index]) 1409 if (probe[index])
1410 hwif_init(&ide_hwifs[index]); 1410 hwif_init(&ide_hwifs[index]);
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index 5faaff87d580..4bd4bf02e917 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -1,6 +1,6 @@
1 1
2/* 2/*
3 * linux/drivers/ide/pci/it821x.c Version 0.10 Mar 10 2007 3 * linux/drivers/ide/pci/it821x.c Version 0.15 Jun 2 2007
4 * 4 *
5 * Copyright (C) 2004 Red Hat <alan@redhat.com> 5 * Copyright (C) 2004 Red Hat <alan@redhat.com>
6 * Copyright (C) 2007 Bartlomiej Zolnierkiewicz 6 * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
@@ -262,7 +262,7 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
262 } 262 }
263 263
264 if (itdev->smart) 264 if (itdev->smart)
265 goto set_drive_speed; 265 return 0;
266 266
267 /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */ 267 /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
268 itdev->want[unit][1] = pio_want[set_pio]; 268 itdev->want[unit][1] = pio_want[set_pio];
@@ -271,7 +271,6 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
271 it821x_clock_strategy(drive); 271 it821x_clock_strategy(drive);
272 it821x_program(drive, itdev->pio[unit]); 272 it821x_program(drive, itdev->pio[unit]);
273 273
274set_drive_speed:
275 return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio); 274 return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
276} 275}
277 276
@@ -455,12 +454,12 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed)
455 default: 454 default:
456 return 1; 455 return 1;
457 } 456 }
457
458 return ide_config_drive_speed(drive, speed);
458 } 459 }
459 /* 460
460 * In smart mode the clocking is done by the host controller 461 /* don't touch anything in the smart mode */
461 * snooping the mode we picked. The rest of it is not our problem 462 return 0;
462 */
463 return ide_config_drive_speed(drive, speed);
464} 463}
465 464
466/** 465/**
@@ -559,17 +558,10 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
559 if(idbits[129] != 1) 558 if(idbits[129] != 1)
560 printk("(%dK stripe)", idbits[146]); 559 printk("(%dK stripe)", idbits[146]);
561 printk(".\n"); 560 printk(".\n");
562 /* Now the core code will have wrongly decided no DMA
563 so we need to fix this */
564 hwif->dma_off_quietly(drive);
565#ifdef CONFIG_IDEDMA_ONLYDISK
566 if (drive->media == ide_disk)
567#endif
568 ide_set_dma(drive);
569 } else { 561 } else {
570 /* Non RAID volume. Fixups to stop the core code 562 /* Non RAID volume. Fixups to stop the core code
571 doing unsupported things */ 563 doing unsupported things */
572 id->field_valid &= 1; 564 id->field_valid &= 3;
573 id->queue_depth = 0; 565 id->queue_depth = 0;
574 id->command_set_1 = 0; 566 id->command_set_1 = 0;
575 id->command_set_2 &= 0xC400; 567 id->command_set_2 &= 0xC400;
@@ -584,6 +576,16 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
584 printk(KERN_INFO "%s: Performing identify fixups.\n", 576 printk(KERN_INFO "%s: Performing identify fixups.\n",
585 drive->name); 577 drive->name);
586 } 578 }
579
580 /*
581 * Set MWDMA0 mode as enabled/support - just to tell
582 * IDE core that DMA is supported (it821x hardware
583 * takes care of DMA mode programming).
584 */
585 if (id->capability & 1) {
586 id->dma_mword |= 0x0101;
587 drive->current_speed = XFER_MW_DMA_0;
588 }
587 } 589 }
588 590
589} 591}