Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7670df73fba373d19471a2ebedb3302ea0607be0
Commit:     7670df73fba373d19471a2ebedb3302ea0607be0
Parent:     a8028fcb485522c0d7de9c5423812de9224b37c9
Author:     Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
AuthorDate: Thu Oct 11 23:53:59 2007 +0200
Committer:  Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
CommitDate: Thu Oct 11 23:53:59 2007 +0200

    ide: mode limiting fixes for user requested speed changes
    
    * Add an extra argument to ide_max_dma_mode() for passing requested transfer
      mode.  Use it as an upper limit when finding the best DMA for device/host.
    
    * Rename ide_max_dma_mode() to ide_find_dma_mode() and at the same time add
      ide_max_dma_mode() wrapper which passes XFER_UDMA_6 as a requested mode to
      ide_find_dma_mode().  Also add inline ide_find_dma_mode() version for
      CONFIG_BLK_DEV_IDEDMA=n case.
    
    * Pass requested transfer mode from ide_find_dma_mode() to 
ide_get_mode_mask()
      to avoid false warning from eighty_ninty_three().
    
    * Use ide_find_dma_mode() to limit the user requested transfer mode in
      ide_rate_filter().  Also limit the requested mode by host max PIO mode.
    
    
    Above changes make ide_rate_filter() to:
    
    * Clip desired transfer mode down if it is invalid (values 0x0F, 0x13-0x19
      and 0x25-0x39, values > 0x46 were already clipped down, same for values
      0x25-0x39 but iff UDMA was not supported by the host).
    
    * Clip desired transfer mode down if it is currently unsupported by IDE core
      (PIO6 and MWDMA3-4, the latter were already clipped down but iff UDMA was
      not supported by the host).
    
    * Clip desired transfer mode down according to the host capabilities
      (UDMA modes were already clipped down but MWDMA/SWDMA/PIO weren't,
      also ->atapi_dma flag was not respected).
    
    * Clip desired transfer mode down according to the device capabilities
      (except PIO modes for now which require mode work) - shouldn't be a
      problem since ide_set_xfer_rate() is called _after_ device has accepted
      given transfer mode.
    
    and also result in a number of host driver specific bugfixes:
    
    * icside
      - clip unsupported PIO5 mode down
      - fix unsupported/invalid modes being set in drive->current_speed
    
    * ide-cris
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - clip DMA modes down for ATAPI devices
      - fix BUG() on unsupported/invalid modes
    
    * au1xxx-ide
      - clip unsupported PIO5, SWDMA0-2 and MWDMA0-2
        (if BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=n) modes down
    
    * aec62xx
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - clip DMA modes down for ATAPI devices
      - fix 0x00 being programmed as PIO timing for unsupported/invalid modes
      - fix unsupported/invalid modes being set on the device
    
    * alim15x3
      - clip DMA modes down for ATAPI devices (chipset revision == 0x20 only)
      - fix theoretical OOPS for 0x0F mode
      - fix unsupported/invalid modes being set on the device
    
    * amd74xx
      - clip unsupported SWDMA0-2 (on COBRA_7401 revs <= 7) modes down
      - fix random PIO timings being set for unsupported/invalid modes
      - fix unsupported/invalid modes being set on the device
    
    * atiixp
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - fix cached MWDMA mode being cleared for unsupported/invalid modes
      - fix PIO{0,2} timings being programmed for unsupported/invalid modes
      - fix theoretical OOPS for PIO5-6 and 0x0F modes
      - fix unsupported/invalid modes being set on the device
    
    * cmd64x
      - clip unsupported SWDMA0-2 modes down
    
    * cs5530
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - fix unsupported/invalid modes being set on the device
      - fix BUG() on unsupported/invalid modes
        (which happened if the device accepted the setting)
    
    * cs5535
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - fix unsupported/invalid modes being set on the device
      - fix theoretical OOPS for PIO5-6 and 0x0F modes
    
    * hpt34x
      - clip DMA modes down for ATAPI devices
      - fix invalid timings being programmed for unsupported/invalid modes
      - fix unsupported/invalid modes being set on the device
    
    * hpt366
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - fix PIO0 timings being programmed for unsupported/invalid modes
      - fix DMA timings being cleared for MWDMA3-4 and 0x25-0x39 modes
      - fix unsupported/invalid modes being set on the device
    
    * it8213
      - clip unsupported PIO5, SWDMA0-1 and MWDMA0 modes down
    
    * it821x
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - clip DMA modes down for ATAPI devices
        (chipset in smart mode and revision 0x10 in pass-through mode)
    
    * jmicron
      - clip unsupported SWDMA0-2 modes down
      - fix unsupported/invalid modes being set on the device
    
    * pdc202xx_new
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - fix unsupported/invalid modes being set on the device
    
    * pdc202xx_old
      - clip unsupported PIO5 mode down
      - fix incorrect timings being set for unsupported/invalid modes
      - fix unsupported/invalid modes being set on the device
    
    * piix
      - clip unsupported PIO5, SWDMA0-1 and MWDMA0 modes down
    
    * sc1200
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - fix unsupported/invalid modes being set on the device
      - fix BUG() on unsupported/invalid modes
        (which happened if the device accepted the setting)
    
    * scc_pata
      - clip unsupported PIO5, SWDMA0-2 and MWDMA0-2 modes down
    
    * serverworks
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - fix DMA/UDMA timings/settings being cleared for unsupported/invalid 
modes
      - fix unsupported/invalid modes being set on the device
    
    * siimage
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - clip DMA modes down for ATAPI devices (SATA chipsets)
    
    * sis5513
      - clip unsupported PIO5 mode down
      - fix BUG() on unsupported/invalid modes
    
    * sl82c105
      - clip unsupported SWDMA0-2 modes down
    
    * slc90e66
      - clip unsupported PIO5, SWDMA0-1 and MWDMA0 modes down
    
    * tc86c001
      - clip unsupported PIO5 and SWDMA0-2 modes down
      - fix PIO0 timings being programmed for PIO5/0x0F/SWDMA0-2/0x13-0x19 modes
      - fix invalid 0x00 DMA timing being programmed for MWDMA3-4/0x25-0x39 
modes
      - fix unsupported/invalid modes being set on the device
    
    * triflex
      - clip unsupported PIO5 mode down
    
    * via82cxxx
      - fix random PIO timings being set for unsupported/invalid modes
      - fix unsupported/invalid modes being set on the device
    
    * pmac
      - clip unsupported PIO5 and SWDMA0-2 modes down
    
    * cmd640/ht6560b
      - clip DMA modes down (if CONFIG_BLK_DEV_IDEDMA=y)
      - fix PIO5 being clipped to PIO4 (if CONFIG_BLK_DEV_IDEDMA=n)
    
    * opti621
      - clip DMA modes down (if CONFIG_BLK_DEV_IDEDMA=y)
      - clip unsupported PIO4 to PIO3 (if CONFIG_BLK_DEV_IDEDMA=n)
    
    
    While at it:
    
    * Use ide_rate_filter() in cs5520.c::cs5520_tune_chipset().
    
    * Remove no longer needed checks from hpt366.c::hpt3{6,7}x_tune_chipset().
    
    Acked-by: Sergei Shtylyov <[EMAIL PROTECTED]>
    Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
---
 drivers/ide/ide-dma.c    |   32 +++++++++++++++++++++-----------
 drivers/ide/ide-lib.c    |   29 ++++++++---------------------
 drivers/ide/pci/cs5520.c |    2 +-
 drivers/ide/pci/hpt366.c |    8 --------
 include/linux/ide.h      |   10 +++++++++-
 5 files changed, 39 insertions(+), 42 deletions(-)

diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index f073ea3..6000c08 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -653,7 +653,7 @@ static const u8 xfer_mode_bases[] = {
        XFER_SW_DMA_0,
 };
 
-static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base)
+static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
 {
        struct hd_driveid *id = drive->id;
        ide_hwif_t *hwif = drive->hwif;
@@ -670,8 +670,13 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, 
u8 base)
                        mask = hwif->ultra_mask;
                mask &= id->dma_ultra;
 
-               if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
-                       mask &= 0x07;
+               /*
+                * avoid false cable warning from eighty_ninty_three()
+                */
+               if (req_mode > XFER_UDMA_2) {
+                       if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
+                               mask &= 0x07;
+               }
                break;
        case XFER_MW_DMA_0:
                if ((id->field_valid & 2) == 0)
@@ -709,15 +714,18 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, 
u8 base)
 }
 
 /**
- *     ide_max_dma_mode        -       compute DMA speed
+ *     ide_find_dma_mode       -       compute DMA speed
  *     @drive: IDE device
+ *     @req_mode: requested mode
+ *
+ *     Checks the drive/host capabilities and finds the speed to use for
+ *     the DMA transfer.  The speed is then limited by the requested mode.
  *
- *     Checks the drive capabilities and returns the speed to use
- *     for the DMA transfer.  Returns 0 if the drive is incapable
- *     of DMA transfers.
+ *     Returns 0 if the drive/host combination is incapable of DMA transfers
+ *     or if the requested mode is not a DMA mode.
  */
 
-u8 ide_max_dma_mode(ide_drive_t *drive)
+u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode)
 {
        ide_hwif_t *hwif = drive->hwif;
        unsigned int mask;
@@ -728,7 +736,9 @@ u8 ide_max_dma_mode(ide_drive_t *drive)
                return 0;
 
        for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) {
-               mask = ide_get_mode_mask(drive, xfer_mode_bases[i]);
+               if (req_mode < xfer_mode_bases[i])
+                       continue;
+               mask = ide_get_mode_mask(drive, xfer_mode_bases[i], req_mode);
                x = fls(mask) - 1;
                if (x >= 0) {
                        mode = xfer_mode_bases[i] + x;
@@ -738,10 +748,10 @@ u8 ide_max_dma_mode(ide_drive_t *drive)
 
        printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode);
 
-       return mode;
+       return min(mode, req_mode);
 }
 
-EXPORT_SYMBOL_GPL(ide_max_dma_mode);
+EXPORT_SYMBOL_GPL(ide_find_dma_mode);
 
 int ide_tune_dma(ide_drive_t *drive)
 {
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 92a6c7b..41a128f 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -76,37 +76,24 @@ EXPORT_SYMBOL(ide_xfer_verbose);
  *     Given the available transfer modes this function returns
  *     the best available speed at or below the speed requested.
  *
- *     FIXME: filter also PIO/SWDMA/MWDMA modes
+ *     TODO: check device PIO capabilities
  */
 
 u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
 {
-#ifdef CONFIG_BLK_DEV_IDEDMA
        ide_hwif_t *hwif = drive->hwif;
-       u8 mask = hwif->ultra_mask, mode = XFER_MW_DMA_2;
-
-       if (hwif->udma_filter)
-               mask = hwif->udma_filter(drive);
-
-       /*
-        * TODO: speed > XFER_UDMA_2 extra check is needed to avoid false
-        * cable warning from eighty_ninty_three(), moving ide_rate_filter()
-        * calls from ->speedproc to core code will make this hack go away
-        */
-       if (speed > XFER_UDMA_2) {
-               if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
-                       mask &= 0x07;
-       }
+       u8 mode = ide_find_dma_mode(drive, speed);
 
-       if (mask)
-               mode = fls(mask) - 1 + XFER_UDMA_0;
+       if (mode == 0) {
+               if (hwif->pio_mask)
+                       mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
+               else
+                       mode = XFER_PIO_4;
+       }
 
 //     printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed);
 
        return min(speed, mode);
-#else /* !CONFIG_BLK_DEV_IDEDMA */
-       return min(speed, (u8)XFER_PIO_4);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
 }
 
 EXPORT_SYMBOL(ide_rate_filter);
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index b89e816..5079810 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -70,7 +70,7 @@ static int cs5520_tune_chipset(ide_drive_t *drive, u8 
xferspeed)
 {
        ide_hwif_t *hwif = HWIF(drive);
        struct pci_dev *pdev = hwif->pci_dev;
-       u8 speed = min((u8)XFER_PIO_4, xferspeed);
+       u8 speed = ide_rate_filter(drive, xferspeed);
        int pio = speed;
        u8 reg;
        int controller = drive->dn > 1 ? 1 : 0;
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 3d8d6b2..18c8ad0 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -610,10 +610,6 @@ static int hpt36x_tune_chipset(ide_drive_t *drive, u8 
xferspeed)
        u32 old_itr             = 0;
        u32 itr_mask, new_itr;
 
-       /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
-       if (drive->media != ide_disk)
-               speed = min_t(u8, speed, XFER_PIO_4);
-
        itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 :
                  (speed < XFER_UDMA_0   ? 0xc0070000 : 0xc03800ff);
 
@@ -642,10 +638,6 @@ static int hpt37x_tune_chipset(ide_drive_t *drive, u8 
xferspeed)
        u32 old_itr             = 0;
        u32 itr_mask, new_itr;
 
-       /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
-       if (drive->media != ide_disk)
-               speed = min_t(u8, speed, XFER_PIO_4);
-
        itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 :
                  (speed < XFER_UDMA_0   ? 0xc03c0000 : 0xc1c001ff);
 
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 80ea946..a3f9c21 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1296,7 +1296,14 @@ int ide_in_drive_list(struct hd_driveid *, const struct 
drive_list_entry *);
 #ifdef CONFIG_BLK_DEV_IDEDMA
 int __ide_dma_bad_drive(ide_drive_t *);
 int __ide_dma_good_drive(ide_drive_t *);
-u8 ide_max_dma_mode(ide_drive_t *);
+
+u8 ide_find_dma_mode(ide_drive_t *, u8);
+
+static inline u8 ide_max_dma_mode(ide_drive_t *drive)
+{
+       return ide_find_dma_mode(drive, XFER_UDMA_6);
+}
+
 int ide_tune_dma(ide_drive_t *);
 void ide_dma_off(ide_drive_t *);
 void ide_dma_verbose(ide_drive_t *);
@@ -1322,6 +1329,7 @@ extern void ide_dma_timeout(ide_drive_t *);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 #else
+static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; }
 static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
 static inline int ide_tune_dma(ide_drive_t *drive) { return 0; }
 static inline void ide_dma_off(ide_drive_t *drive) { ; }
-
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