Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9445de76c124e90176b5116cf82f6cd1413f5230
Commit:     9445de76c124e90176b5116cf82f6cd1413f5230
Parent:     4fce3164b84d5b014acbf5a3f57eb3650e154f5b
Author:     Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
AuthorDate: Wed May 16 00:51:42 2007 +0200
Committer:  Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
CommitDate: Wed May 16 00:51:42 2007 +0200

    serverworks: PIO mode setup fixes
    
    * limit max PIO mode to PIO4, this driver doesn't support PIO5 and attempt
      to program PIO5 by svwks_tune_chipset() could result in incorrect PIO
      timings being programmed and possibly the data corruption (it seems that
      the minimum possible values were used but I lack the datasheets to be 
sure)
    
    * select best PIO mode in svwks_tune_drive() and not in svwks_tune_chipset()
      when doing PIO autotuning (pio == 255)
    
    * don't try to tune PIO in config_chipset_for_dma() as ide_dma_enable() 
could
      return 1 if DMA was previously enabled (svwks_config_drive_xfer_rate()
      takes care of PIO tuning if no suitable DMA mode is found)
    
    * remove config_chipset_for_pio() and use svwks_tune_drive() instead,
      config_chipset_for_pio() contained numerous bugs when selecting PIO mode
      (luckily it was only used for devices limited to PIO by 
capabilities/BIOS):
    
      - it didn't check for validity of id->eide_pio_modes and 
id->eide_pio_iordy
        before using them
    
      - it tried to found out maximum PIO mode basing on minimum IORDY cycle 
time
        (moreover wrong cycle times were used for PIO0/1/5)
    
      - it was overriding PIO blacklist and conservative PIO "downgrade" done
        by ide_get_best_pio_mode()
    
      - if the max drive PIO was PIO5 then XFER_PIO_0/XFER_PIO_SLOW was selected
        (XFER_PIO_SLOW is not supported by svwks_tune_chipset() so the result
         was the same as if using XFER_PIO_5 => wrong PIO timings were set)
    
      - it was overriding drive->current_speed
    
    * bump driver version
    
    Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
---
 drivers/ide/pci/serverworks.c |   68 +++++++++--------------------------------
 1 files changed, 15 insertions(+), 53 deletions(-)

diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index 2fa6d92..a94e77d 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -1,9 +1,10 @@
 /*
- * linux/drivers/ide/pci/serverworks.c         Version 0.8      25 Ebr 2003
+ * linux/drivers/ide/pci/serverworks.c         Version 0.9     Mar 4 2007
  *
  * Copyright (C) 1998-2000 Michel Aubry
  * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
  * Copyright (C) 1998-2000 Andre Hedrick <[EMAIL PROTECTED]>
+ * Copyright (C)      2007 Bartlomiej Zolnierkiewicz
  * Portions copyright (c) 2001 Sun Microsystems
  *
  *
@@ -136,19 +137,14 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 
xferspeed)
 
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
-       u8 speed;
-       u8 pio                  = ide_get_best_pio_mode(drive, 255, 5, NULL);
+       u8 speed                = ide_rate_filter(drive, xferspeed);
+       u8 pio                  = ide_get_best_pio_mode(drive, 255, 4, NULL);
        u8 unit                 = (drive->select.b.unit & 0x01);
        u8 csb5                 = svwks_csb_check(dev);
        u8 ultra_enable         = 0, ultra_timing = 0;
        u8 dma_timing           = 0, pio_timing = 0;
        u16 csb5_pio            = 0;
 
-       if (xferspeed == 255)   /* PIO auto-tuning */
-               speed = XFER_PIO_0 + pio;
-       else
-               speed = ide_rate_filter(drive, xferspeed);
-
        /* If we are about to put a disk into UDMA mode we screwed up.
           Our code assumes we never _ever_ do this on an OSB4 */
           
@@ -231,6 +227,9 @@ oem_setup_failed:
                case XFER_MW_DMA_2:
                case XFER_MW_DMA_1:
                case XFER_MW_DMA_0:
+                       /*
+                        * TODO: always setup PIO mode so this won't be needed
+                        */
                        pio_timing |= pio_modes[pio];
                        csb5_pio   |= (pio << (4*drive->dn));
                        dma_timing |= dma_modes[speed - XFER_MW_DMA_0];
@@ -242,6 +241,9 @@ oem_setup_failed:
                case XFER_UDMA_2:
                case XFER_UDMA_1:
                case XFER_UDMA_0:
+                       /*
+                        * TODO: always setup PIO mode so this won't be needed
+                        */
                        pio_timing   |= pio_modes[pio];
                        csb5_pio     |= (pio << (4*drive->dn));
                        dma_timing   |= dma_modes[2];
@@ -262,58 +264,18 @@ oem_setup_failed:
        return (ide_config_drive_speed(drive, speed));
 }
 
-static void config_chipset_for_pio (ide_drive_t *drive)
-{
-       u16 eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
-       u16 xfer_pio = drive->id->eide_pio_modes;
-       u8 timing, speed, pio;
-
-       pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
-
-       if (xfer_pio > 4)
-               xfer_pio = 0;
-
-       if (drive->id->eide_pio_iordy > 0)
-               for (xfer_pio = 5;
-                       xfer_pio>0 &&
-                       drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
-                       xfer_pio--);
-       else
-               xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-                          (drive->id->eide_pio_modes & 2) ? 0x04 :
-                          (drive->id->eide_pio_modes & 1) ? 0x03 :
-                          (drive->id->tPIO & 2) ? 0x02 :
-                          (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
-
-       timing = (xfer_pio >= pio) ? xfer_pio : pio;
-
-       switch(timing) {
-               case 4: speed = XFER_PIO_4;break;
-               case 3: speed = XFER_PIO_3;break;
-               case 2: speed = XFER_PIO_2;break;
-               case 1: speed = XFER_PIO_1;break;
-               default:
-                       speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
-                       break;
-       }
-       (void) svwks_tune_chipset(drive, speed);
-       drive->current_speed = speed;
-}
-
 static void svwks_tune_drive (ide_drive_t *drive, u8 pio)
 {
-       if(pio == 255)
-               (void) svwks_tune_chipset(drive, 255);
-       else
-               (void) svwks_tune_chipset(drive, (XFER_PIO_0 + pio));
+       pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+       (void)svwks_tune_chipset(drive, XFER_PIO_0 + pio);
 }
 
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
        u8 speed = ide_max_dma_mode(drive);
 
-       if (!(speed))
-               speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
+       if (!speed)
+               return 0;
 
        (void) svwks_tune_chipset(drive, speed);
        return ide_dma_enable(drive);
@@ -327,7 +289,7 @@ static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
                return 0;
 
        if (ide_use_fast_pio(drive))
-               config_chipset_for_pio(drive);
+               svwks_tune_drive(drive, 255);
 
        return -1;
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to