]> err.no Git - linux-2.6/blobdiff - drivers/ide/pci/piix.c
ide: move ide_rate_filter() calls to the upper layer (take 2)
[linux-2.6] / drivers / ide / pci / piix.c
index 8b219dd630241f4285512e61a9b417872c5147e8..b66f9d1411b35c18d92709b58cb35979f8af5db2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/piix.c       Version 0.47    February 8, 2007
+ *  linux/drivers/ide/pci/piix.c       Version 0.51    Jul 6, 2007
  *
  *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
  *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
@@ -109,7 +109,7 @@ static int no_piix_dma;
  *     piix_dma_2_pio          -       return the PIO mode matching DMA
  *     @xfer_rate: transfer speed
  *
- *     Returns the nearest equivalent PIO timing for the PIO or DMA
+ *     Returns the nearest equivalent PIO timing for the DMA
  *     mode requested by the controller.
  */
  
@@ -123,20 +123,14 @@ static u8 piix_dma_2_pio (u8 xfer_rate) {
                case XFER_UDMA_1:
                case XFER_UDMA_0:
                case XFER_MW_DMA_2:
-               case XFER_PIO_4:
                        return 4;
                case XFER_MW_DMA_1:
-               case XFER_PIO_3:
                        return 3;
                case XFER_SW_DMA_2:
-               case XFER_PIO_2:
                        return 2;
                case XFER_MW_DMA_0:
                case XFER_SW_DMA_1:
                case XFER_SW_DMA_0:
-               case XFER_PIO_1:
-               case XFER_PIO_0:
-               case XFER_PIO_SLOW:
                default:
                        return 0;
        }
@@ -219,7 +213,7 @@ static void piix_tune_pio (ide_drive_t *drive, u8 pio)
  */
 static void piix_tune_drive (ide_drive_t *drive, u8 pio)
 {
-       pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+       pio = ide_get_best_pio_mode(drive, pio, 4);
        piix_tune_pio(drive, pio);
        (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
 }
@@ -227,19 +221,18 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
 /**
  *     piix_tune_chipset       -       tune a PIIX interface
  *     @drive: IDE drive to tune
- *     @xferspeed: speed to configure
+ *     @speed: speed to configure
  *
  *     Set a PIIX interface channel to the desired speeds. This involves
  *     requires the right timing data into the PIIX configuration space
  *     then setting the drive parameters appropriately
  */
-static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
+
+static int piix_tune_chipset(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
        u8 maslave              = hwif->channel ? 0x42 : 0x40;
-       u8 speed                = ide_rate_filter(drive, xferspeed);
        int a_speed             = 3 << (drive->dn * 4);
        int u_flag              = 1 << drive->dn;
        int v_flag              = 0x01 << drive->dn;
@@ -269,6 +262,7 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
                case XFER_PIO_4:
                case XFER_PIO_3:
                case XFER_PIO_2:
+               case XFER_PIO_1:
                case XFER_PIO_0:        break;
                default:                return -1;
        }
@@ -299,7 +293,11 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
                        pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
        }
 
-       piix_tune_pio(drive, piix_dma_2_pio(speed));
+       if (speed > XFER_PIO_4)
+               piix_tune_pio(drive, piix_dma_2_pio(speed));
+       else
+               piix_tune_pio(drive, speed - XFER_PIO_0);
+
        return ide_config_drive_speed(drive, speed);
 }
 
@@ -394,14 +392,45 @@ static void piix_dma_clear_irq(ide_drive_t *drive)
        hwif->OUTB(dma_stat, hwif->dma_status);
 }
 
-static int __devinit piix_cable_detect(ide_hwif_t *hwif)
+struct ich_laptop {
+       u16 device;
+       u16 subvendor;
+       u16 subdevice;
+};
+
+/*
+ *     List of laptops that use short cables rather than 80 wire
+ */
+
+static const struct ich_laptop ich_laptop[] = {
+       /* devid, subvendor, subdev */
+       { 0x27DF, 0x0005, 0x0280 },     /* ICH7 on Acer 5602WLMi */
+       { 0x27DF, 0x1025, 0x0110 },     /* ICH7 on Acer 3682WLMi */
+       { 0x27DF, 0x1043, 0x1267 },     /* ICH7 on Asus W5F */
+       { 0x24CA, 0x1025, 0x0061 },     /* ICH4 on Acer Aspire 2023WLMi */
+       /* end marker */
+       { 0, }
+};
+
+static u8 __devinit piix_cable_detect(ide_hwif_t *hwif)
 {
-       struct pci_dev *dev = hwif->pci_dev;
+       struct pci_dev *pdev = hwif->pci_dev;
+       const struct ich_laptop *lap = &ich_laptop[0];
        u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30;
 
-       pci_read_config_byte(dev, 0x54, &reg54h);
+       /* check for specials */
+       while (lap->device) {
+               if (lap->device == pdev->device &&
+                   lap->subvendor == pdev->subsystem_vendor &&
+                   lap->subdevice == pdev->subsystem_device) {
+                       return ATA_CBL_PATA40_SHORT;
+               }
+               lap++;
+       }
+
+       pci_read_config_byte(pdev, 0x54, &reg54h);
 
-       return (reg54h & mask) ? 1 : 0;
+       return (reg54h & mask) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
 }
 
 /**
@@ -444,8 +473,8 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
        hwif->swdma_mask = 0x04;
 
        if (hwif->ultra_mask & 0x78) {
-               if (!hwif->udma_four)
-                       hwif->udma_four = piix_cable_detect(hwif);
+               if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+                       hwif->cbl = piix_cable_detect(hwif);
        }
 
        if (no_piix_dma)
@@ -464,10 +493,10 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
                .name           = name_str,             \
                .init_chipset   = init_chipset_piix,    \
                .init_hwif      = init_hwif_piix,       \
-               .channels       = 2,                    \
                .autodma        = AUTODMA,              \
                .enablebits     = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
                .bootable       = ON_BOARD,             \
+               .pio_mask       = ATA_PIO4,             \
                .udma_mask      = udma,                 \
        }
 
@@ -483,11 +512,11 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = {
                 */
                .name           = "MPIIX",
                .init_hwif      = init_hwif_piix,
-               .channels       = 2,
                .autodma        = NODMA,
                .enablebits     = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}},
                .bootable       = ON_BOARD,
-               .flags          = IDEPCI_FLAG_ISA_PORTS
+               .host_flags     = IDE_HFLAG_ISA_PORTS,
+               .pio_mask       = ATA_PIO4,
        },
 
        /*  3 */ DECLARE_PIIX_DEV("PIIX3", 0x00),       /* no udma */
@@ -541,18 +570,16 @@ static void __devinit piix_check_450nx(void)
 {
        struct pci_dev *pdev = NULL;
        u16 cfg;
-       u8 rev;
        while((pdev=pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev))!=NULL)
        {
                /* Look for 450NX PXB. Check for problem configurations
                   A PCI quirk checks bit 6 already */
-               pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
                pci_read_config_word(pdev, 0x41, &cfg);
                /* Only on the original revision: IDE DMA can hang */
-               if(rev == 0x00)
+               if (pdev->revision == 0x00)
                        no_piix_dma = 1;
                /* On all revisions below 5 PXB bus lock must be disabled for IDE */
-               else if(cfg & (1<<14) && rev < 5)
+               else if (cfg & (1<<14) && pdev->revision < 5)
                        no_piix_dma = 2;
        }
        if(no_piix_dma)