]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/ide-iops.c
ide: add ide_dev_is_sata() helper (take 2)
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-iops.c
index f0be5f665a0e0ae21af516609c0a82c556b4e0cd..646a54e233d361451bfab4982a1da96956be82a2 100644 (file)
@@ -565,6 +565,36 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b
 
 EXPORT_SYMBOL(ide_wait_stat);
 
+/**
+ *     ide_in_drive_list       -       look for drive in black/white list
+ *     @id: drive identifier
+ *     @drive_table: list to inspect
+ *
+ *     Look for a drive in the blacklist and the whitelist tables
+ *     Returns 1 if the drive is found in the table.
+ */
+
+int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
+{
+       for ( ; drive_table->id_model; drive_table++)
+               if ((!strcmp(drive_table->id_model, id->model)) &&
+                   (!drive_table->id_firmware ||
+                    strstr(id->fw_rev, drive_table->id_firmware)))
+                       return 1;
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(ide_in_drive_list);
+
+/*
+ * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid.
+ * We list them here and depend on the device side cable detection for them.
+ */
+static const struct drive_list_entry ivb_list[] = {
+       { "QUANTUM FIREBALLlct10 05"    , "A03.0900"    },
+       { NULL                          , NULL          }
+};
+
 /*
  *  All hosts that use the 80c ribbon must use!
  *  The name is derived from upper byte of word 93 and the 80c ribbon.
@@ -573,22 +603,29 @@ u8 eighty_ninty_three (ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
        struct hd_driveid *id = drive->id;
+       int ivb = ide_in_drive_list(id, ivb_list);
+
+       if (hwif->cbl == ATA_CBL_PATA40_SHORT)
+               return 1;
+
+       if (ivb)
+               printk(KERN_DEBUG "%s: skipping word 93 validity check\n",
+                                 drive->name);
 
-       if (hwif->udma_four == 0)
+       if (hwif->cbl != ATA_CBL_PATA80 && !ivb)
                goto no_80w;
 
-       /* Check for SATA but only if we are ATA5 or higher */
-       if (id->hw_config == 0 && (id->major_rev_num & 0x7FE0))
+       if (ide_dev_is_sata(id))
                return 1;
 
        /*
         * FIXME:
         * - change master/slave IDENTIFY order
-        * - force bit13 (80c cable present) check
+        * - force bit13 (80c cable present) check also for !ivb devices
         *   (unless the slave device is pre-ATA3)
         */
 #ifndef CONFIG_IDEDMA_IVB
-       if (id->hw_config & 0x4000)
+       if ((id->hw_config & 0x4000) || (ivb && (id->hw_config & 0x2000)))
 #else
        if (id->hw_config & 0x6000)
 #endif
@@ -600,7 +637,8 @@ no_80w:
 
        printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, "
                            "limiting max speed to UDMA33\n",
-                           drive->name, hwif->udma_four ? "drive" : "host");
+                           drive->name,
+                           hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host");
 
        drive->udma33_warned = 1;
 
@@ -791,7 +829,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed)
                hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
        hwif->OUTB(speed, IDE_NSECTOR_REG);
        hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG);
-       hwif->OUTB(WIN_SETFEATURES, IDE_COMMAND_REG);
+       hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG);
        if ((IDE_CONTROL_REG) && (drive->quirk_list == 2))
                hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
        udelay(1);
@@ -818,7 +856,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed)
         */
        for (i = 0; i < 10; i++) {
                udelay(1);
-               if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) {
+               if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), drive->ready_stat, BUSY_STAT|DRQ_STAT|ERR_STAT)) {
                        error = 0;
                        break;
                }