drive->id[ATA_ID_UDMA_MODES]  = id[ATA_ID_UDMA_MODES];
        drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES];
        drive->id[ATA_ID_SWDMA_MODES] = id[ATA_ID_SWDMA_MODES];
+       drive->id[ATA_ID_CFA_MODES]   = id[ATA_ID_CFA_MODES];
        /* anything more ? */
 
        kfree(id);
                id[ATA_ID_UDMA_MODES]  &= ~0xFF00;
                id[ATA_ID_MWDMA_MODES] &= ~0x0700;
                id[ATA_ID_SWDMA_MODES] &= ~0x0700;
-       }
+               if (ata_id_is_cfa(id))
+                       id[ATA_ID_CFA_MODES] &= ~0x0E00;
+       } else  if (ata_id_is_cfa(id))
+               id[ATA_ID_CFA_MODES] &= ~0x01C0;
 
  skip:
 #ifdef CONFIG_BLK_DEV_IDEDMA
        if (speed >= XFER_UDMA_0) {
                i = 1 << (speed - XFER_UDMA_0);
                id[ATA_ID_UDMA_MODES] |= (i << 8 | i);
+       } else if (ata_id_is_cfa(id) && speed >= XFER_MW_DMA_3) {
+               i = speed - XFER_MW_DMA_2;
+               id[ATA_ID_CFA_MODES] |= i << 9;
        } else if (speed >= XFER_MW_DMA_0) {
                i = 1 << (speed - XFER_MW_DMA_0);
                id[ATA_ID_MWDMA_MODES] |= (i << 8 | i);
        } else if (speed >= XFER_SW_DMA_0) {
                i = 1 << (speed - XFER_SW_DMA_0);
                id[ATA_ID_SWDMA_MODES] |= (i << 8 | i);
+       } else if (ata_id_is_cfa(id) && speed >= XFER_PIO_5) {
+               i = speed - XFER_PIO_4;
+               id[ATA_ID_CFA_MODES] |= i << 6;
        }
 
        if (!drive->init_speed)
 
        { XFER_UDMA_1,     0,   0,   0,   0,   0,   0,   0,  80 },
        { XFER_UDMA_0,     0,   0,   0,   0,   0,   0,   0, 120 },
 
+       { XFER_MW_DMA_4,  25,   0,   0,   0,  55,  20,  80,   0 },
+       { XFER_MW_DMA_3,  25,   0,   0,   0,  65,  25, 100,   0 },
        { XFER_MW_DMA_2,  25,   0,   0,   0,  70,  25, 120,   0 },
        { XFER_MW_DMA_1,  45,   0,   0,   0,  80,  50, 150,   0 },
        { XFER_MW_DMA_0,  60,   0,   0,   0, 215, 215, 480,   0 },
        { XFER_SW_DMA_1,  90,   0,   0,   0, 240, 240, 480,   0 },
        { XFER_SW_DMA_0, 120,   0,   0,   0, 480, 480, 960,   0 },
 
-       { XFER_PIO_5,     20,  50,  30, 100,  50,  30, 100,   0 },
+       { XFER_PIO_6,     10,  55,  20,  80,  55,  20,  80,   0 },
+       { XFER_PIO_5,     15,  65,  25, 100,  65,  25, 100,   0 },
        { XFER_PIO_4,     25,  70,  25, 120,  70,  25, 120,   0 },
        { XFER_PIO_3,     30,  80,  70, 180,  80,  70, 180,   0 },
 
                /* conservative "downgrade" for all pre-ATA2 drives */
                if (pio < 3 && cycle < t->cycle)
                        cycle = 0; /* use standard timing */
+
+               /* Use the standard timing for the CF specific modes too */
+               if (pio > 4 && ata_id_is_cfa(id))
+                       cycle = 0;
        }
 
        return cycle ? cycle : t->cycle;
 
                if (speed <= XFER_PIO_2)
                        p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
-               else if (speed <= XFER_PIO_5)
+               else if ((speed <= XFER_PIO_4) ||
+                        (speed == XFER_PIO_5 && !ata_id_is_cfa(id)))
                        p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY];
                else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
                        p.cycle = id[ATA_ID_EIDE_DMA_MIN];
 
         { "UDMA/16", "UDMA/25",  "UDMA/33",  "UDMA/44",
           "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
 static const char *mwdma_str[] =
-       { "MWDMA0", "MWDMA1", "MWDMA2" };
+       { "MWDMA0", "MWDMA1", "MWDMA2", "MWDMA3", "MWDMA4" };
 static const char *swdma_str[] =
        { "SWDMA0", "SWDMA1", "SWDMA2" };
 static const char *pio_str[] =
-       { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
+       { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5", "PIO6" };
 
 /**
  *     ide_xfer_verbose        -       return IDE mode names
 
        if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
                s = udma_str[i];
-       else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
+       else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_4)
                s = mwdma_str[i];
        else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
                s = swdma_str[i];
-       else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
+       else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_6)
                s = pio_str[i & 0x7];
        else if (mode == XFER_PIO_SLOW)
                s = "PIO SLOW";
                }
 
                if (id[ATA_ID_FIELD_VALID] & 2) {             /* ATA2? */
-                       if (ata_id_has_iordy(id)) {
+                       if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 7))
+                               pio_mode = 4 + min_t(int, 2,
+                                                    id[ATA_ID_CFA_MODES] & 7);
+                       else if (ata_id_has_iordy(id)) {
                                if (id[ATA_ID_PIO_MODES] & 7) {
                                        overridden = 0;
                                        if (id[ATA_ID_PIO_MODES] & 4)
 
        BUG_ON(rate < XFER_PIO_0);
 
-       if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
+       if (rate >= XFER_PIO_0 && rate <= XFER_PIO_6)
                return ide_set_pio_mode(drive, rate);
 
        return ide_set_dma_mode(drive, rate);