struct hd_driveid* id = drive->id;
        int overridden  = 0;
 
-       if (mode_wanted != 255) {
-               pio_mode = mode_wanted;
-       } else if (!drive->id) {
-               pio_mode = 0;
-       } else if ((pio_mode = ide_scan_pio_blacklist(id->model)) != -1) {
+       if (mode_wanted != 255)
+               return min_t(u8, mode_wanted, max_mode);
+
+       if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0 &&
+           (pio_mode = ide_scan_pio_blacklist(id->model)) != -1) {
                printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
        } else {
                pio_mode = id->tPIO;
                /*
                 * Conservative "downgrade" for all pre-ATA2 drives
                 */
-               if (pio_mode && pio_mode < 4) {
+               if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_DOWNGRADE) == 0 &&
+                   pio_mode && pio_mode < 4) {
                        pio_mode--;
                        printk(KERN_INFO "%s: applying conservative "
                                         "PIO \"downgrade\"\n", drive->name);
 
 #define XFER_EPIO      0x01
 #define XFER_PIO       0x00
 
-static short ide_find_best_pio_mode(ide_drive_t *drive)
-{
-       struct hd_driveid *id = drive->id;
-       short best = 0;
-
-       /* EIDE PIO modes */
-       if ((id->field_valid & 2) && (id->capability & 8)) {
-               if ((best = (drive->id->eide_pio_modes & 4) ? XFER_PIO_5 :
-                           (drive->id->eide_pio_modes & 2) ? XFER_PIO_4 :
-                           (drive->id->eide_pio_modes & 1) ? XFER_PIO_3 : 0)) return best;
-       }
-
-       return XFER_PIO_0 + min_t(u8, id->tPIO, 2);
-}
-
 static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int T, int UT)
 {
        q->setup   = EZ(t->setup   * 1000,  T);
  */
 
        if ((speed & XFER_MODE) != XFER_PIO) {
-               ide_timing_compute(drive, ide_find_best_pio_mode(drive), &p, T, UT);
+               u8 pio = ide_get_best_pio_mode(drive, 255, 5);
+               ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT);
                ide_timing_merge(&p, t, t, IDE_TIMING_ALL);
        }
 
 
        hwif->straight8                 = tmp_hwif->straight8;
        hwif->bus_state                 = tmp_hwif->bus_state;
 
+       hwif->host_flags                = tmp_hwif->host_flags;
+
        hwif->atapi_dma                 = tmp_hwif->atapi_dma;
        hwif->ultra_mask                = tmp_hwif->ultra_mask;
        hwif->mwdma_mask                = tmp_hwif->mwdma_mask;
 
 /*
- * Version 2.20
+ * Version 2.21
  *
  * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04
  * IDE driver for Linux.
 
 static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio)
 {
-       if (pio == 255) {
-               amd_set_drive(drive, ide_find_best_pio_mode(drive));
-               return;
-       }
+       if (pio == 255)
+               pio = ide_get_best_pio_mode(drive, 255, 5);
 
        amd_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5));
 }
 {
        u8 speed = ide_max_dma_mode(drive);
 
-       if (speed == 0)
-               speed = ide_find_best_pio_mode(drive);
+       if (speed == 0) {
+               amd74xx_tune_drive(drive, 255);
+               return -1;
+       }
 
        amd_set_drive(drive, speed);
 
-       if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
+       if (drive->autodma)
                return 0;
 
        return -1;
                .autodma        = AUTODMA,                              \
                .enablebits     = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
                .bootable       = ON_BOARD,                             \
+               .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST            \
+                               | IDE_HFLAG_PIO_NO_DOWNGRADE,           \
        }
 
 #define DECLARE_NV_DEV(name_str)                                       \
                .autodma        = AUTODMA,                              \
                .enablebits     = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
                .bootable       = ON_BOARD,                             \
+               .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST            \
+                               | IDE_HFLAG_PIO_NO_DOWNGRADE,           \
        }
 
 static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
 
 /*
  *
- * Version 3.45
+ * Version 3.46
  *
  * VIA IDE driver for Linux. Supported southbridges:
  *
 
 static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
 {
-       if (pio == 255) {
-               via_set_drive(drive, ide_find_best_pio_mode(drive));
-               return;
-       }
+       if (pio == 255)
+               pio = ide_get_best_pio_mode(drive, 255, 5);
 
        via_set_drive(drive, XFER_PIO_0 + min_t(u8, pio, 5));
 }
 {
        u8 speed = ide_max_dma_mode(drive);
 
-       if (speed == 0)
-               speed = ide_find_best_pio_mode(drive);
+       if (speed == 0) {
+               via82cxxx_tune_drive(drive, 255);
+               return -1;
+       }
 
        via_set_drive(drive, speed);
 
-       if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
+       if (drive->autodma)
                return 0;
 
        return -1;
                .init_hwif      = init_hwif_via82cxxx,
                .autodma        = NOAUTODMA,
                .enablebits     = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
-               .bootable       = ON_BOARD
+               .bootable       = ON_BOARD,
+               .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST
+                               | IDE_HFLAG_PIO_NO_DOWNGRADE,
        },{     /* 1 */
                .name           = "VP_IDE",
                .init_chipset   = init_chipset_via82cxxx,
                .autodma        = AUTODMA,
                .enablebits     = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
                .bootable       = ON_BOARD,
+               .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST
+                               | IDE_HFLAG_PIO_NO_DOWNGRADE,
        }
 };
 
 
                else
                        ide_hwif_setup_dma(dev, d, hwif);
 bypass_legacy_dma:
+               hwif->host_flags = d->host_flags;
+
                if (d->init_hwif)
                        /* Call chipset-specific routine
                         * for each enabled hwif
 
        u8 straight8;   /* Alan's straight 8 check */
        u8 bus_state;   /* power state of the IDE bus */
 
+       u8 host_flags;
+
        u8 atapi_dma;   /* host supports atapi_dma */
        u8 ultra_mask;
        u8 mwdma_mask;
 enum {
        /* Uses ISA control ports not PCI ones. */
        IDE_HFLAG_ISA_PORTS             = (1 << 0),
+       /* single port device */
        IDE_HFLAG_SINGLE                = (1 << 1),
+       /* don't use legacy PIO blacklist */
+       IDE_HFLAG_PIO_NO_BLACKLIST      = (1 << 2),
+       /* don't use conservative PIO "downgrade" */
+       IDE_HFLAG_PIO_NO_DOWNGRADE      = (1 << 3),
 };
 
 typedef struct ide_pci_device_s {