Hi,

On Friday 18 May 2007, Thomas Kuther wrote:
> On Mi, 16.05.07 11:46 Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
> wrote:
> 
> > > Shall I test it without "noraid=1" too? 
> > 
> > Please do, the main goal of the patch was to fix "RAID mode"
> > ("noraid=1" should work fine also without the patch?).
> > 
> > Thanks,
> > Bart
> 
> Hi,
> 
> sorry for late response. Now the results in smart mode:
> ---------------------------------------------------
> IT8212: IDE controller at PCI slot 0000:00:09.0
> ACPI: PCI Interrupt 0000:00:09.0[A] -> GSI 17 (level, low) -> IRQ 18
> IT8212: chipset revision 17
> it821x: controller in smart mode.
> IT8212: 100% native mode on irq 18
>     ide2: BM-DMA at 0xdc00-0xdc07, BIOS settings: hde:pio, hdf:pio
>     ide3: BM-DMA at 0xdc08-0xdc0f, BIOS settings: hdg:pio, hdh:pio
> Probing IDE interface ide2...
> hde: SAMSUNG SP2514N, ATA DISK drive
> hdf: Maxtor 6Y120L0, ATA DISK drive
> hde: Performing identify fixups.
> hdf: Performing identify fixups.
> ide2 at 0xec00-0xec07,0xe802 on irq 18
> hde: max request size: 128KiB
> hde: 488397168 sectors (250059 MB) w/8192KiB Cache, CHS=30401/255/63
>  hde:hde: recal_intr: status=0x51 { DriveReady SeekComplete Error }
> hde: recal_intr: error=0x04 { DriveStatusError }
> ide: failed opcode was: unknown
>  hde1
> hdf: max request size: 128KiB
> hdf: 240121728 sectors (122942 MB) w/2048KiB Cache, CHS=65535/16/63
>  hdf:hdf: recal_intr: status=0x51 { DriveReady SeekComplete Error }
> hdf: recal_intr: error=0x04 { DriveStatusError }
> ide: failed opcode was: unknown
>  hdf1
> ------------------------------------------------------
> 
> # hdparm -d1 /dev/hde
> 
> /dev/hde:
>  setting using_dma to 1 (on)
>  HDIO_SET_DMA failed: Input/output error
>  using_dma     =  0 (off)
> 
> -------------------------------------------------------
> 
> Buffered reads: 3.06MB/s
> 
> Seems I shot too quick, DMA in smart mode still does not work.
> "noraid=1" also works without the patch, correct.

Improved patch - this time the issue should be fixed for good (I was
looking only at the RAID specific part of the fixups and I overlooked
the fact that the original code was clearing too much of id->field_valid),
there is now also an extra debugging printk to give us some more info.

Please give it a try.

[ recal_intr warning (which should be harmless) is not fixed by this
  patch because it is a different problem and requires some more work. ]

---
 drivers/ide/ide-probe.c  |   12 ++++++------
 drivers/ide/pci/it821x.c |   38 +++++++++++++++++++++++---------------
 2 files changed, 29 insertions(+), 21 deletions(-)

Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -717,7 +717,7 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
  * This routine only knows how to look for drive units 0 and 1
  * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
  */
-static void probe_hwif(ide_hwif_t *hwif)
+static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
 {
        unsigned int unit;
        unsigned long flags;
@@ -820,6 +820,9 @@ static void probe_hwif(ide_hwif_t *hwif)
                return;
        }
 
+       if (fixup)
+               fixup(hwif);
+
        for (unit = 0; unit < MAX_DRIVES; ++unit) {
                ide_drive_t *drive = &hwif->drives[unit];
 
@@ -874,10 +877,7 @@ static int hwif_init(ide_hwif_t *hwif);
 
 int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t 
*hwif))
 {
-       probe_hwif(hwif);
-
-       if (fixup)
-               fixup(hwif);
+       probe_hwif(hwif, fixup);
 
        if (!hwif_init(hwif)) {
                printk(KERN_INFO "%s: failed to initialize IDE interface\n",
@@ -1404,7 +1404,7 @@ int ideprobe_init (void)
 
        for (index = 0; index < MAX_HWIFS; ++index)
                if (probe[index])
-                       probe_hwif(&ide_hwifs[index]);
+                       probe_hwif(&ide_hwifs[index], NULL);
        for (index = 0; index < MAX_HWIFS; ++index)
                if (probe[index])
                        hwif_init(&ide_hwifs[index]);
Index: b/drivers/ide/pci/it821x.c
===================================================================
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -262,7 +262,7 @@ static int it821x_tunepio(ide_drive_t *d
        }
 
        if (itdev->smart)
-               goto set_drive_speed;
+               return 0;
 
        /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
        itdev->want[unit][1] = pio_want[set_pio];
@@ -271,7 +271,6 @@ static int it821x_tunepio(ide_drive_t *d
        it821x_clock_strategy(drive);
        it821x_program(drive, itdev->pio[unit]);
 
-set_drive_speed:
        return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
 }
 
@@ -455,12 +454,12 @@ static int it821x_tune_chipset (ide_driv
                        default:
                                return 1;
                }
+
+               return ide_config_drive_speed(drive, speed);
        }
-       /*
-        *      In smart mode the clocking is done by the host controller
-        *      snooping the mode we picked. The rest of it is not our problem
-        */
-       return ide_config_drive_speed(drive, speed);
+
+       /* don't touch anything in the smart mode */
+       return 0;
 }
 
 /**
@@ -543,6 +542,13 @@ static void __devinit it821x_fixups(ide_
                id = drive->id;
                idbits = (u16 *)drive->id;
 
+               /* debug */
+               printk(KERN_INFO "%s: field_valid=%04x capability=%02x "
+                                "dma_mword=%04x dma_status=%02x\n",
+                                drive->name,
+                                id->field_valid, id->capability,
+                                id->dma_mword, inb(hwif->dma_status));
+
                /* Check for RAID v native */
                if(strstr(id->model, "Integrated Technology Express")) {
                        /* In raid mode the ident block is slightly buggy
@@ -559,17 +565,10 @@ static void __devinit it821x_fixups(ide_
                                if(idbits[129] != 1)
                                        printk("(%dK stripe)", idbits[146]);
                                printk(".\n");
-                       /* Now the core code will have wrongly decided no DMA
-                          so we need to fix this */
-                       hwif->dma_off_quietly(drive);
-#ifdef CONFIG_IDEDMA_ONLYDISK
-                       if (drive->media == ide_disk)
-#endif
-                               ide_set_dma(drive);
                } else {
                        /* Non RAID volume. Fixups to stop the core code
                           doing unsupported things */
-                       id->field_valid &= 1;
+                       id->field_valid &= 3;
                        id->queue_depth = 0;
                        id->command_set_1 = 0;
                        id->command_set_2 &= 0xC400;
@@ -584,6 +583,15 @@ static void __devinit it821x_fixups(ide_
                        printk(KERN_INFO "%s: Performing identify fixups.\n",
                                drive->name);
                }
+
+               /*
+                * Set MWDMA0 mode as enabled/support - just to tell
+                * IDE core that DMA is supported (it821x hardware
+                * takes care of DMA mode programming).
+                */
+               id->capability |= 1;
+               id->dma_mword |= 0x0101;
+               drive->current_speed = XFER_MW_DMA_0;
        }
 
 }

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to