Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6b8cf7724bd0f8ae1f61937c5f40f4dbbda40960
Commit:     6b8cf7724bd0f8ae1f61937c5f40f4dbbda40960
Parent:     9445de76c124e90176b5116cf82f6cd1413f5230
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

    sis5513: PIO mode setup fixes
    
    * limit max PIO mode to PIO4, this driver doesn't support PIO5 and attempt
      to program PIO5 by config_art_rwp_pio() could result in incorrect PIO
      timings being programmed and possibly the data corruption (for < ATA100
      family chipsets PIO0 timings were used, for ATA100 and ATA100a - the 
random
      content of test1 variable was used, for ATA133 - MWDMA0 timings were used)
    
    * BUG() in sis5513_tune_chipset() if somebody tries to force unsupported 
PIO5,
      also cleanup this function a bit while at it
    
    * add comment about PIO0 timings for < ATA100 family chipsets
    
    * remove open-coded best PIO mode selection from config_art_rwp_pio(),
      it contained numerous bugs:
    
      - 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 PIO1/5)
    
      - it was overriding PIO blacklist and conservative PIO "downgrade" done
        by ide_get_best_pio_mode()
    
    * use sis5513_tune_drive() instead of config_art_rwp_pio()
      in sis5513_config_xfer_rate() so the correct PIO mode is also set
      on drive even if the device is not IORDY/DMA capable
    
    * config_art_rwp_pio() was always setting the best possible mode and not
      the wanted one - fix it and move ide_get_best_pio_mode() call to
      config_chipset_for_pio()
    
    * don't use ide_find_best_mode() in config_chipset_for_pio(), it was being
      overriden by config_art_rwp_pio() for the host timings anyway + we need to
      set the same PIO mode on the device and the host
    
    * pass correct "pio" argument (255 instead of 5) to sis5513_tune_drive() 
call
      in sis5513_config_xfer_rate() so the best PIO mode is set on the drive
      and not PIO4
    
    * rename sis5513_tune_drive() to sis5513_tuneproc()
      and config_chipset_for_pio() to sis5513_tune_driver()
    
    * bump driver version
    
    Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
---
 drivers/ide/pci/sis5513.c |   85 +++++++++++++++++++--------------------------
 1 files changed, 36 insertions(+), 49 deletions(-)

diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 2bde1b9..bb6cc4a 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -1,9 +1,11 @@
 /*
- * linux/drivers/ide/pci/sis5513.c     Version 0.16ac+vp       Jun 18, 2003
+ * linux/drivers/ide/pci/sis5513.c     Version 0.20    Mar 4, 2007
  *
  * Copyright (C) 1999-2000     Andre Hedrick <[EMAIL PROTECTED]>
  * Copyright (C) 2002          Lionel Bouton <[EMAIL PROTECTED]>, Maintainer
  * Copyright (C) 2003          Vojtech Pavlik <[EMAIL PROTECTED]>
+ * Copyright (C) 2007          Bartlomiej Zolnierkiewicz
+ *
  * May be copied or modified under the terms of the GNU General Public License
  *
  *
@@ -448,36 +450,15 @@ static void config_drive_art_rwp (ide_drive_t *drive)
                pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);
 }
 
-
 /* Set per-drive active and recovery time */
 static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
 
-       u8                      timing, drive_pci, test1, test2;
-
-       u16 eide_pio_timing[6] = {600, 390, 240, 180, 120, 90};
-       u16 xfer_pio = drive->id->eide_pio_modes;
+       u8 drive_pci, test1, test2;
 
        config_drive_art_rwp(drive);
-       pio = ide_get_best_pio_mode(drive, 255, pio, 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 : xfer_pio;
-       }
-
-       timing = (xfer_pio >= pio) ? xfer_pio : pio;
 
        /* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */
        drive_pci = 0x40;
@@ -500,17 +481,18 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 
pio)
                test1 &= ~0x0F;
                test2 &= ~0x07;
 
-               switch(timing) {
+               switch(pio) {
                        case 4:         test1 |= 0x01; test2 |= 0x03; break;
                        case 3:         test1 |= 0x03; test2 |= 0x03; break;
                        case 2:         test1 |= 0x04; test2 |= 0x04; break;
                        case 1:         test1 |= 0x07; test2 |= 0x06; break;
+                       case 0:         /* PIO0: register setting == X000 */
                        default:        break;
                }
                pci_write_config_byte(dev, drive_pci, test1);
                pci_write_config_byte(dev, drive_pci+1, test2);
        } else if (chipset_family < ATA_133) {
-               switch(timing) { /*             active  recovery
+               switch(pio) { /*                active  recovery
                                                  v     v */
                        case 4:         test1 = 0x30|0x01; break;
                        case 3:         test1 = 0x30|0x03; break;
@@ -525,24 +507,28 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 
pio)
                pci_read_config_dword(dev, drive_pci, &test3);
                test3 &= 0xc0c00fff;
                if (test3 & 0x08) {
-                       test3 |= (unsigned long)ini_time_value[ATA_133][timing] 
<< 12;
-                       test3 |= (unsigned long)act_time_value[ATA_133][timing] 
<< 16;
-                       test3 |= (unsigned long)rco_time_value[ATA_133][timing] 
<< 24;
+                       test3 |= ini_time_value[ATA_133][pio] << 12;
+                       test3 |= act_time_value[ATA_133][pio] << 16;
+                       test3 |= rco_time_value[ATA_133][pio] << 24;
                } else {
-                       test3 |= (unsigned long)ini_time_value[ATA_100][timing] 
<< 12;
-                       test3 |= (unsigned long)act_time_value[ATA_100][timing] 
<< 16;
-                       test3 |= (unsigned long)rco_time_value[ATA_100][timing] 
<< 24;
+                       test3 |= ini_time_value[ATA_100][pio] << 12;
+                       test3 |= act_time_value[ATA_100][pio] << 16;
+                       test3 |= rco_time_value[ATA_100][pio] << 24;
                }
                pci_write_config_dword(dev, drive_pci, test3);
        }
 }
 
-static int config_chipset_for_pio (ide_drive_t *drive, u8 pio)
+static int sis5513_tune_drive(ide_drive_t *drive, u8 pio)
 {
-       if (pio == 255)
-               pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - 
XFER_PIO_0;
+       pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
        config_art_rwp_pio(drive, pio);
-       return ide_config_drive_speed(drive, XFER_PIO_0 + min_t(u8, pio, 4));
+       return ide_config_drive_speed(drive, XFER_PIO_0 + pio);
+}
+
+static void sis5513_tuneproc(ide_drive_t *drive, u8 pio)
+{
+       (void)sis5513_tune_drive(drive, pio);
 }
 
 static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
@@ -622,25 +608,26 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 
xferspeed)
                case XFER_SW_DMA_1:
                case XFER_SW_DMA_0:
                        break;
-               case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4));
-               case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3));
-               case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2));
-               case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
+               case XFER_PIO_4:
+               case XFER_PIO_3:
+               case XFER_PIO_2:
+               case XFER_PIO_1:
                case XFER_PIO_0:
-               default:         return((int) config_chipset_for_pio(drive, 
0));        
+                       return sis5513_tune_drive(drive, speed - XFER_PIO_0);
+               default:
+                       BUG();
+                       break;
        }
 
-       return ((int) ide_config_drive_speed(drive, speed));
-}
-
-static void sis5513_tune_drive (ide_drive_t *drive, u8 pio)
-{
-       (void) config_chipset_for_pio(drive, pio);
+       return ide_config_drive_speed(drive, speed);
 }
 
 static int sis5513_config_xfer_rate(ide_drive_t *drive)
 {
-       config_art_rwp_pio(drive, 5);
+       /*
+        * TODO: always set PIO mode and remove this
+        */
+       sis5513_tuneproc(drive, 255);
 
        drive->init_speed = 0;
 
@@ -648,7 +635,7 @@ static int sis5513_config_xfer_rate(ide_drive_t *drive)
                return 0;
 
        if (ide_use_fast_pio(drive))
-               sis5513_tune_drive(drive, 5);
+               sis5513_tuneproc(drive, 255);
 
        return -1;
 }
@@ -836,7 +823,7 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
        if (!hwif->irq)
                hwif->irq = hwif->channel ? 15 : 14;
 
-       hwif->tuneproc = &sis5513_tune_drive;
+       hwif->tuneproc = &sis5513_tuneproc;
        hwif->speedproc = &sis5513_tune_chipset;
 
        if (!(hwif->dma_base)) {
-
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