Skip to contentSkip to conversation

IDE BIOS timings, autotune cleanup

PATCH In review Torben Mathiasen 2 participants 3 messages Nov 1, 2002 – Nov 2, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 IDE BIOS timings, autotune cleanup

Hi,

The attached patch cleans up the 'autotune' concept used in the current 2.4 IDE driver. It also adds support for using pure BIOS IDE timings with DMA/PIO. On some systems the BIOS has a far better overview on how things are connected (some chipsets don't support >ata66 speed detection, etc).

The patch introduces 2 new boot parameters in addtion to the current two autotune options (autotune vs. noautotune):

ide0=autotune -> kernel IDE timing setup
ide0=noautotune -> BIOS IDE timing setup (PIO only)
ide0=noautotune_dma -> BIOS IDE timing setup (DMA/PIO)
ide0=noautotune_force -> BIOS IDE (DMA/PIO), chipset *cannot* override.

Default is autotune (as always) and chipsets can override the other options unless *_force is used.

All chipset drivers updated. Tested with PIIX and Serverworks.

Regards,
Torben Mathiasen

include/linux/ide.h +9 -1
@@ -88,6 +88,14 @@
 #define ERROR_RECAL	1	/* Recalibrate every 2nd retry */
 
 /*
+ * Chipset autotune defines
+ */
+#define BIOS_IDE_ON_FORCED	4   /* BIOS IDE setup forced (DMA/PIO) */
+#define BIOS_IDE_ON_DMA 	3   /* BIOS IDE setup supporting DMA/PIO */
+#define BIOS_IDE_ON		2   /* BIOS IDE setup supporting PIO */
+#define BIOS_IDE_OFF		1   /* Let kernel tune IDE timings */
+#define BIOS_IDE_DEFAULT	BIOS_IDE_OFF
+/*
  * state flags
  */
 #define DMA_PIO_RETRY	1	/* retrying in PIO */
@@ -378,7 +386,7 @@
 	unsigned nice0		: 1;	/* flag: give obvious excess bandwidth */
 	unsigned nice2		: 1;	/* flag: give a share in our own bandwidth */
 	unsigned doorlocking	: 1;	/* flag: for removable only: door lock/unlock works */
-	unsigned autotune	: 2;	/* 1=autotune, 2=noautotune, 0=default */
+	unsigned autotune	: 4;	/* 1=autotune, 2=noautotune, 3=noautotune_dma, 4=noautotune_force */
 	unsigned remap_0_to_1	: 2;	/* 0=remap if ezdrive, 1=remap, 2=noremap */
 	unsigned ata_flash	: 1;	/* 1=present, 0=default */
 	unsigned	addressing;	/* : 2; 0=28-bit, 1=48-bit, 2=64-bit */
drivers/ide/aec62xx.c +2 -2
diff -u linux-2.4.20-rc1-clean/drivers/ide/aec62xx.c linux-2.4.20-rc1-idepatch/drivers/ide/aec62xx.c
@@ -558,8 +558,8 @@
 	if (hwif->dma_base)
 		hwif->dmaproc = &aec62xx_dmaproc;
 #else /* !CONFIG_BLK_DEV_IDEDMA */
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->drives[0].autotune = BIOS_IDE_OFF;
+	hwif->drives[1].autotune = BIOS_IDE_OFF;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 #endif /* CONFIG_AEC62XX_TUNING */
 }
drivers/ide/alim15x3.c +2 -2
diff -u linux-2.4.20-rc1-clean/drivers/ide/alim15x3.c linux-2.4.20-rc1-idepatch/drivers/ide/alim15x3.c
@@ -676,8 +676,8 @@
 #endif /* CONFIG_SPARC64 */
 
 	hwif->tuneproc = &ali15x3_tune_drive;
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->drives[0].autotune = BIOS_IDE_OFF;
+	hwif->drives[1].autotune = BIOS_IDE_OFF;
 	hwif->speedproc = &ali15x3_tune_chipset;
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
drivers/ide/amd74xx.c +4 -4
diff -u linux-2.4.20-rc1-clean/drivers/ide/amd74xx.c linux-2.4.20-rc1-idepatch/drivers/ide/amd74xx.c
@@ -489,8 +489,8 @@
 	hwif->speedproc = &amd74xx_tune_chipset;
 
 #ifndef CONFIG_BLK_DEV_IDEDMA
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->drives[0].autotune = BIOS_IDE_OFF;
+	hwif->drives[1].autotune = BIOS_IDE_OFF;
 	hwif->autodma = 0;
 	return;
 #else
@@ -501,8 +501,8 @@
 			hwif->autodma = 1;
 	} else {
 		hwif->autodma = 0;
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
+		hwif->drives[0].autotune = BIOS_IDE_OFF;
+		hwif->drives[1].autotune = BIOS_IDE_OFF;
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 }
drivers/ide/cmd640.c +1 -1
diff -u linux-2.4.20-rc1-clean/drivers/ide/cmd640.c linux-2.4.20-rc1-idepatch/drivers/ide/cmd640.c
@@ -816,7 +816,7 @@
 	for (index = 0; index < (2 + (second_port_cmd640 << 1)); index++) {
 		ide_drive_t *drive = cmd_drives[index];
 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
-		if (drive->autotune || ((index > 1) && second_port_toggled)) {
+		if ((drive->autotune == BIOS_IDE_OFF) || ((index > 1) && second_port_toggled)) {
 	 		/*
 	 		 * Reset timing to the slowest speed and turn off prefetch.
 			 * This way, the drive identify code has a better chance.
drivers/ide/cmd64x.c +2 -2
diff -u linux-2.4.20-rc1-clean/drivers/ide/cmd64x.c linux-2.4.20-rc1-idepatch/drivers/ide/cmd64x.c
@@ -1124,8 +1124,8 @@
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
 
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->drives[0].autotune = BIOS_IDE_OFF;
+	hwif->drives[1].autotune = BIOS_IDE_OFF;
 
 	if (!hwif->dma_base)
 		return;
drivers/ide/cs5530.c +2 -2
diff -u linux-2.4.20-rc1-clean/drivers/ide/cs5530.c linux-2.4.20-rc1-idepatch/drivers/ide/cs5530.c
@@ -363,12 +363,12 @@
 		if (CS5530_BAD_PIO(d0_timings)) {	/* PIO timings not initialized? */
 			outl(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+0);
 			if (!hwif->drives[0].autotune)
-				hwif->drives[0].autotune = 1;	/* needs autotuning later */
+				hwif->drives[0].autotune = BIOS_IDE_OFF;    /* needs autotuning later */
 		}
 		if (CS5530_BAD_PIO(inl(basereg+8))) {	/* PIO timings not initialized? */
 			outl(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+8);
 			if (!hwif->drives[1].autotune)
-				hwif->drives[1].autotune = 1;	/* needs autotuning later */
+				hwif->drives[1].autotune = BIOS_IDE_OFF;	/* needs autotuning later */
 		}
 	}
 }
drivers/ide/cy82c693.c +2 -2
diff -u linux-2.4.20-rc1-clean/drivers/ide/cy82c693.c linux-2.4.20-rc1-idepatch/drivers/ide/cy82c693.c
@@ -435,8 +435,8 @@
 {
 	hwif->chipset = ide_cy82c693;
 	hwif->tuneproc = &cy82c693_tune_drive;
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->drives[0].autotune = BIOS_IDE_OFF;
+	hwif->drives[1].autotune = BIOS_IDE_OFF;
 	hwif->autodma = 0;
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
drivers/ide/hpt34x.c +4 -4
diff -u linux-2.4.20-rc1-clean/drivers/ide/hpt34x.c linux-2.4.20-rc1-idepatch/drivers/ide/hpt34x.c
@@ -426,12 +426,12 @@
 
 		hwif->dmaproc = &hpt34x_dmaproc;
 	} else {
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
+		hwif->drives[0].autotune = BIOS_IDE_OFF;
+		hwif->drives[1].autotune = BIOS_IDE_OFF;
 	}
 #else /* !CONFIG_BLK_DEV_IDEDMA */
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->drives[0].autotune = BIOS_IDE_OFF;
+	hwif->drives[1].autotune = BIOS_IDE_OFF;
 	hwif->autodma = 0;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 }
drivers/ide/hpt366.c +4 -4
diff -u linux-2.4.20-rc1-clean/drivers/ide/hpt366.c linux-2.4.20-rc1-idepatch/drivers/ide/hpt366.c
@@ -1198,12 +1198,12 @@
 			hwif->autodma = 0;
 	} else {
 		hwif->autodma = 0;
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
+		hwif->drives[0].autotune = BIOS_IDE_OFF;
+		hwif->drives[1].autotune = BIOS_IDE_OFF;
 	}
 #else /* !CONFIG_BLK_DEV_IDEDMA */
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->drives[0].autotune = BIOS_IDE_OFF;
+	hwif->drives[1].autotune = BIOS_IDE_OFF;
 	hwif->autodma = 0;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 }
drivers/ide/ide-dma.c +16 -3
diff -u linux-2.4.20-rc1-clean/drivers/ide/ide-dma.c linux-2.4.20-rc1-idepatch/drivers/ide/ide-dma.c
@@ -814,9 +814,22 @@
 
 	if (hwif->chipset != ide_trm290) {
 		byte dma_stat = inb(dma_base+2);
-		printk(", BIOS settings: %s:%s, %s:%s",
-		       hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio",
-		       hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio");
+		
+		printk(", BIOS settings: %s:%s%s, %s:%s%s",
+			hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio",
+			hwif->drives[0].autotune == BIOS_IDE_ON_FORCED 
+				? " (forced)" : "",
+            		hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio",
+			hwif->drives[1].autotune == BIOS_IDE_ON_FORCED ? 
+				" (forced)" : "");
+	
+	/* If BIOS_IDE_ON_DMA or BIOS_IDE_ON_FORCED is set we just check 
+	 * whether DMA was enabled by the BIOS or not.
+	 */
+        if (hwif->drives[0].autotune >= BIOS_IDE_ON_DMA)
+		hwif->drives[0].using_dma = (dma_stat & 0x20);
+        if (hwif->drives[1].autotune >= BIOS_IDE_ON_DMA)
+		hwif->drives[1].using_dma = (dma_stat & 0x40);
 	}
 	printk("\n");
 	return;
drivers/ide/ide-pci.c +12 -0
diff -u linux-2.4.20-rc1-clean/drivers/ide/ide-pci.c linux-2.4.20-rc1-idepatch/drivers/ide/ide-pci.c
@@ -611,6 +611,7 @@
 	ide_hwif_t *hwif, *mate = NULL;
 	unsigned int class_rev;
 	static int secondpdc = 0;
+    int drive0_tune = 0, drive1_tune = 0;
 
 #ifdef CONFIG_IDEDMA_AUTO
 	if (!noautodma)
@@ -859,8 +860,19 @@
 bypass_legacy_dma:
 bypass_piix_dma:
 bypass_umc_dma:
+        /* Record drive tune value as some chipset will try to override */
+        drive0_tune = hwif->drives[0].autotune;
+        drive1_tune = hwif->drives[1].autotune;
+        
 		if (d->init_hwif)  /* Call chipset-specific routine for each enabled hwif */
 			d->init_hwif(hwif);
+        
+        if (drive0_tune == BIOS_IDE_ON_FORCED) /* drive 0 forced BIOS settings */
+            hwif->drives[0].autotune = drive0_tune;
+
+        if (drive1_tune == BIOS_IDE_ON_FORCED) /* drive 1 forced BIOS settings */
+            hwif->drives[1].autotune = drive1_tune;
+
 		mate = hwif;
 		at_least_one_hwif_enabled = 1;
 	}
drivers/ide/ide-probe.c +3 -2
diff -u linux-2.4.20-rc1-clean/drivers/ide/ide-probe.c linux-2.4.20-rc1-idepatch/drivers/ide/ide-probe.c
@@ -340,7 +340,8 @@
 	{
 		if ((rc = try_to_identify(drive,cmd)))   /* send cmd and wait */
 			rc = try_to_identify(drive,cmd); /* failed: try again */
-		if (rc == 1 && cmd == WIN_PIDENTIFY && drive->autotune != 2) {
+		if (rc == 1 && cmd == WIN_PIDENTIFY && 
+                drive->autotune <= BIOS_IDE_OFF)  {
 			unsigned long timeout;
 			printk("%s: no response (status = 0x%02x), resetting drive\n", drive->name, GET_STAT());
 			ide_delay_50ms();
@@ -565,7 +566,7 @@
 		ide_drive_t *drive = &hwif->drives[unit];
 		if (drive->present) {
 			ide_tuneproc_t *tuneproc = HWIF(drive)->tuneproc;
-			if (tuneproc != NULL && drive->autotune == 1)
+			if (tuneproc != NULL && drive->autotune == BIOS_IDE_OFF)
 				tuneproc(drive, 255);	/* auto-tune PIO mode */
 		}
 	}
drivers/ide/ide.c +55 -15

144 lines not on this page · raw message

drivers/ide/it8172.c +2 -2
diff -u linux-2.4.20-rc1-clean/drivers/ide/it8172.c linux-2.4.20-rc1-idepatch/drivers/ide/it8172.c
@@ -261,8 +261,8 @@
     unsigned long cmdBase, ctrlBase;
     
     hwif->tuneproc = &it8172_tune_drive;
-    hwif->drives[0].autotune = 1;
-    hwif->drives[1].autotune = 1;
+    hwif->drives[0].autotune = BIOS_IDE_OFF;
+    hwif->drives[1].autotune = BIOS_IDE_OFF;
 
     if (!hwif->dma_base)
 	return;
drivers/ide/pdc202xx.c +4 -4
diff -u linux-2.4.20-rc1-clean/drivers/ide/pdc202xx.c linux-2.4.20-rc1-idepatch/drivers/ide/pdc202xx.c
@@ -1176,13 +1176,13 @@
 		if (!noautodma)
 			hwif->autodma = 1;
 	} else {
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
+		hwif->drives[0].autotune = BIOS_IDE_OFF;
+		hwif->drives[1].autotune = BIOS_IDE_OFF;
 		hwif->autodma = 0;
 	}
 #else /* !CONFIG_BLK_DEV_IDEDMA */
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->drives[0].autotune = BIOS_IDE_OFF;
+	hwif->drives[1].autotune = BIOS_IDE_OFF;
 	hwif->autodma = 0;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 }
drivers/ide/piix.c +5 -5
diff -u linux-2.4.20-rc1-clean/drivers/ide/piix.c linux-2.4.20-rc1-idepatch/drivers/ide/piix.c
@@ -521,11 +521,11 @@
 		/* This is a painful system best to let it self tune for now */
 		return;
 	}
-
-	hwif->tuneproc = &piix_tune_drive;
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-
+    
+    hwif->tuneproc = &piix_tune_drive;
+    hwif->drives[0].autotune = BIOS_IDE_OFF;
+    hwif->drives[1].autotune = BIOS_IDE_OFF;
+	
 	if (!hwif->dma_base)
 		return;
 
drivers/ide/serverworks.c +4 -4
diff -u linux-2.4.20-rc1-clean/drivers/ide/serverworks.c linux-2.4.20-rc1-idepatch/drivers/ide/serverworks.c
@@ -656,8 +656,8 @@
 	hwif->speedproc = &svwks_tune_chipset;
 
 #ifndef CONFIG_BLK_DEV_IDEDMA
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->drives[0].autotune = BIOS_IDE_OFF;
+	hwif->drives[1].autotune = BIOS_IDE_OFF;
 	hwif->autodma = 0;
 #else /* CONFIG_BLK_DEV_IDEDMA */
 	if (hwif->dma_base) {
@@ -668,8 +668,8 @@
 		hwif->dmaproc = &svwks_dmaproc;
 	} else {
 		hwif->autodma = 0;
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
+		hwif->drives[0].autotune = BIOS_IDE_OFF;
+		hwif->drives[1].autotune = BIOS_IDE_OFF;
 	}
 #endif /* !CONFIG_BLK_DEV_IDEDMA */
 }
drivers/ide/sl82c105.c +2 -2
diff -u linux-2.4.20-rc1-clean/drivers/ide/sl82c105.c linux-2.4.20-rc1-idepatch/drivers/ide/sl82c105.c
@@ -247,8 +247,8 @@
 	rev = sl82c105_bridge_revision(hwif->pci_dev);
 	if (rev <= 5) {
 		hwif->autodma = 0;
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
+		hwif->drives[0].autotune = BIOS_IDE_OFF;
+		hwif->drives[1].autotune = BIOS_IDE_OFF;
 		printk("    %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
 		       hwif->name, rev);
 		dma_state &= ~0x60;
drivers/ide/slc90e66.c +2 -2
diff -u linux-2.4.20-rc1-clean/drivers/ide/slc90e66.c linux-2.4.20-rc1-idepatch/drivers/ide/slc90e66.c
@@ -380,8 +380,8 @@
 		hwif->irq = hwif->channel ? 15 : 14;
 
 	hwif->tuneproc = &slc90e66_tune_drive;
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->drives[0].autotune = BIOS_IDE_OFF;
+	hwif->drives[1].autotune = BIOS_IDE_OFF;
 
 	if (!hwif->dma_base)
 		return;
drivers/ide/via82cxxx.c +1 -1
diff -u linux-2.4.20-rc1-clean/drivers/ide/via82cxxx.c linux-2.4.20-rc1-idepatch/drivers/ide/via82cxxx.c
@@ -539,7 +539,7 @@
 	for (i = 0; i < 2; i++) {
 		hwif->drives[i].io_32bit = 1;
 		hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
-		hwif->drives[i].autotune = 1;
+		hwif->drives[i].autotune = BIOS_IDE_OFF;
 		hwif->drives[i].dn = hwif->channel * 2 + i;
 	}
 
#1 lore raw
Quoted 7 lines · Torben Mathiasen

Hi,

The attached patch cleans up the 'autotune' concept used in the current 2.4 IDE driver. It also adds support for using pure BIOS IDE timings with DMA/PIO. On some systems the BIOS has a far better overview on how things are connected (some chipsets don't support >ata66 speed detection, etc).

Interesting idea. However you are working on whats effectively a dead codebase.

#2 lore raw
Quoted 11 lines · Alan Cox
Quoted 7 lines · Torben Mathiasen

Hi,

The attached patch cleans up the 'autotune' concept used in the current 2.4 IDE driver. It also adds support for using pure BIOS IDE timings with DMA/PIO. On some systems the BIOS has a far better overview on how things are connected (some chipsets don't support >ata66 speed detection, etc).

Interesting idea. However you are working on whats effectively a dead codebase.

Oh :). Let me just port it over to AC and 2.5 for the new IDE layer.

Torben