linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch] My AMD IDE driver, v2.7
@ 2002-03-11 15:13 Vojtech Pavlik
  2002-03-11 16:36 ` Martin Dalecki
  0 siblings, 1 reply; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-11 15:13 UTC (permalink / raw)
  To: Martin Dalecki, Linus Torvalds, LKML

[-- Attachment #1: Type: text/plain, Size: 345 bytes --]

Hi!

This patch replaces the current AMD IDE driver (by Andre Hedrick) by
mine. Myself I think my implementation is much cleaner, but I'll leave
upon others to judge that. My driver also additionally supports the
AMD-8111 IDE.

It's well tested, and I'd like to have this in the kernel instead of
what's there now.

-- 
Vojtech Pavlik
SuSE Labs

[-- Attachment #2: amdide-2.7.diff --]
[-- Type: text/plain, Size: 29756 bytes --]

diff -urN linux-2.5.6/drivers/ide/amd74xx.c linux-2.5.6-amdide/drivers/ide/amd74xx.c
--- linux-2.5.6/drivers/ide/amd74xx.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-amdide/drivers/ide/amd74xx.c	Mon Mar 11 16:02:05 2002
@@ -1,485 +1,451 @@
 /*
- * linux/drivers/ide/amd74xx.c		Version 0.05	June 9, 2000
+ * $Id: amd74xx.c,v 2.7 2002/09/01 17:37:00 vojtech Exp $
  *
- * Copyright (C) 1999-2000		Andre Hedrick <andre@linux-ide.org>
- * May be copied or modified under the terms of the GNU General Public License
+ *  Copyright (c) 2000-2002 Vojtech Pavlik
  *
+ *  Based on the work of:
+ *	Andre Hedrick
+ */
+
+/*
+ * AMD 755/756/766/8111 IDE driver for Linux.
+ *
+ * UDMA66 and higher modes are autoenabled only in case the BIOS has detected a
+ * 80 wire cable. To ignore the BIOS data and assume the cable is present, use
+ * 'ide0=ata66' or 'ide1=ata66' on the kernel command line.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
 #include <linux/config.h>
-#include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/blkdev.h>
-#include <linux/hdreg.h>
-
-#include <linux/interrupt.h>
-#include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/init.h>
 #include <linux/ide.h>
-
 #include <asm/io.h>
-#include <asm/irq.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
+
+#define AMD_IDE_ENABLE		0x40
+#define AMD_IDE_CONFIG		0x41
+#define AMD_CABLE_DETECT	0x42
+#define AMD_DRIVE_TIMING	0x48
+#define AMD_8BIT_TIMING		0x4e
+#define AMD_ADDRESS_SETUP	0x4c
+#define AMD_UDMA_TIMING		0x50
+
+#define AMD_UDMA		0x07
+#define AMD_UDMA_33		0x01
+#define AMD_UDMA_66		0x02
+#define AMD_UDMA_100		0x03
+#define AMD_BAD_SWDMA		0x08
+#define AMD_BAD_FIFO		0x10
 
-#define DISPLAY_VIPER_TIMINGS
+/*
+ * AMD SouthBridge chips.
+ */
+
+static struct amd_ide_chip {
+	char *name;
+	unsigned short id;
+	unsigned char rev;
+	unsigned char flags;
+} amd_ide_chips[] = {
+	{ "8111",		PCI_DEVICE_ID_AMD_8111_IDE,  0x00, AMD_UDMA_100 },
+	{ "768 Opus",		PCI_DEVICE_ID_AMD_OPUS_7441, 0x00, AMD_UDMA_100 },
+	{ "766 Viper",		PCI_DEVICE_ID_AMD_VIPER_7411, 0x00, AMD_UDMA_100 | AMD_BAD_FIFO },
+	{ "756/c4+ Viper",	PCI_DEVICE_ID_AMD_VIPER_7409, 0x07, AMD_UDMA_66 },
+	{ "756 Viper",		PCI_DEVICE_ID_AMD_VIPER_7409, 0x00, AMD_UDMA_66 | AMD_BAD_SWDMA },
+	{ "755 Cobra",		PCI_DEVICE_ID_AMD_COBRA_7401, 0x00, AMD_UDMA_33 | AMD_BAD_SWDMA },
+	{ NULL }
+};
+
+static struct amd_ide_chip *amd_config;
+static unsigned char amd_enabled;
+static unsigned int amd_80w;
+static unsigned int amd_clock;
+
+static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3 };
+static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 1 };
+static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100" };
+
+/*
+ * AMD /proc entry.
+ */
+
+#ifdef CONFIG_PROC_FS
 
-#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
 
-static int amd74xx_get_info(char *, char **, off_t, int);
-extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+byte amd74xx_proc;
+int amd_base;
 static struct pci_dev *bmide_dev;
+extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
 
-static int amd74xx_get_info (char *buffer, char **addr, off_t offset, int count)
-{
+#define amd_print(format, arg...) p += sprintf(p, format "\n" , ## arg)
+#define amd_print_drive(name, format, arg...)\
+	p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n");
+
+static int amd_get_info(char *buffer, char **addr, off_t offset, int count)
+{
+	int speed[4], cycle[4], setup[4], active[4], recover[4], den[4],
+		 uen[4], udma[4], active8b[4], recover8b[4];
+	struct pci_dev *dev = bmide_dev;
+	unsigned int v, u, i;
+	unsigned short c, w;
+	unsigned char t;
 	char *p = buffer;
-	u32 bibma = pci_resource_start(bmide_dev, 4);
-	u8 c0 = 0, c1 = 0;
 
-	/*
-	 * at that point bibma+0x2 et bibma+0xa are byte registers
-	 * to investigate:
-	 */
-	c0 = inb_p((unsigned short)bibma + 0x02);
-	c1 = inb_p((unsigned short)bibma + 0x0a);
-
-	p += sprintf(p, "\n                                AMD %04X VIPER Chipset.\n", bmide_dev->device);
-	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
-	p += sprintf(p, "                %sabled                         %sabled\n",
-			(c0&0x80) ? "dis" : " en",
-			(c1&0x80) ? "dis" : " en");
-	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
-	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
-			(c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
-			(c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
-	p += sprintf(p, "UDMA\n");
-	p += sprintf(p, "DMA\n");
-	p += sprintf(p, "PIO\n");
+	amd_print("----------AMD BusMastering IDE Configuration----------------");
 
-	return p-buffer;	/* => must be less than 4k! */
-}
-#endif  /* defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) */
+	amd_print("Driver Version:                     2.7");
+	amd_print("South Bridge:                       AMD-%s", amd_config->name);
 
-byte amd74xx_proc = 0;
+	pci_read_config_byte(dev, PCI_REVISION_ID, &t);
+	amd_print("Revision:                           IDE %#x", t);
+	amd_print("Highest DMA rate:                   %s", amd_dma[amd_config->flags & AMD_UDMA]);
 
-extern char *ide_xfer_verbose (byte xfer_rate);
+	amd_print("BM-DMA base:                        %#x", amd_base);
+	amd_print("PCI clock:                          %d.%dMHz", amd_clock / 1000, amd_clock / 100 % 10);
+	
+	amd_print("-----------------------Primary IDE-------Secondary IDE------");
 
-static unsigned int amd74xx_swdma_check (struct pci_dev *dev)
-{
-	unsigned int class_rev;
+	pci_read_config_byte(dev, AMD_IDE_CONFIG, &t);
+	amd_print("Prefetch Buffer:       %10s%20s", (t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no");
+	amd_print("Post Write Buffer:     %10s%20s", (t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
 
-	if ((dev->device == PCI_DEVICE_ID_AMD_VIPER_7411) ||
-	    (dev->device == PCI_DEVICE_ID_AMD_VIPER_7441))
-		return 0;
-
-	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xff;
-	return ((int) (class_rev >= 7) ? 1 : 0);
-}
+	pci_read_config_byte(dev, AMD_IDE_ENABLE, &t);
+	amd_print("Enabled:               %10s%20s", (t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no");
 
-static int amd74xx_swdma_error(ide_drive_t *drive)
-{
-	printk("%s: single-word DMA not support (revision < C4)\n", drive->name);
-	return 0;
-}
+	c = inb(amd_base + 0x02) | (inb(amd_base + 0x0a) << 8);
+	amd_print("Simplex only:          %10s%20s", (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no");
 
-/*
- * Here is where all the hard work goes to program the chipset.
- *
- */
-static int amd74xx_tune_chipset (ide_drive_t *drive, byte speed)
-{
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	int err			= 0;
-	byte unit		= (drive->select.b.unit & 0x01);
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	unsigned long dma_base	= hwif->dma_base;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-	byte drive_pci		= 0x00;
-	byte drive_pci2		= 0x00;
-	byte ultra_timing	= 0x00;
-	byte dma_pio_timing	= 0x00;
-	byte pio_timing		= 0x00;
-
-        switch (drive->dn) {
-		case 0: drive_pci = 0x53; drive_pci2 = 0x4b; break;
-		case 1: drive_pci = 0x52; drive_pci2 = 0x4a; break;
-		case 2: drive_pci = 0x51; drive_pci2 = 0x49; break;
-		case 3: drive_pci = 0x50; drive_pci2 = 0x48; break;
-		default:
-                        return -1;
-        }
-
-	pci_read_config_byte(dev, drive_pci, &ultra_timing);
-	pci_read_config_byte(dev, drive_pci2, &dma_pio_timing);
-	pci_read_config_byte(dev, 0x4c, &pio_timing);
-
-#ifdef DEBUG
-	printk("%s:%d: Speed 0x%02x UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
-		drive->name, drive->dn, speed, ultra_timing, dma_pio_timing, pio_timing);
-#endif
+	amd_print("Cable Type:            %10s%20s", (amd_80w & 1) ? "80w" : "40w", (amd_80w & 2) ? "80w" : "40w");
 
-	ultra_timing	&= ~0xC7;
-	dma_pio_timing	&= ~0xFF;
-	pio_timing	&= ~(0x03 << drive->dn);
-
-#ifdef DEBUG
-	printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
-		drive->name, ultra_timing, dma_pio_timing, pio_timing);
-#endif
+	if (!amd_clock)
+                return p - buffer;
 
-	switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
-		case XFER_UDMA_7:
-		case XFER_UDMA_6:
-			speed = XFER_UDMA_5;
-		case XFER_UDMA_5:
-			ultra_timing |= 0x46;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_4:
-			ultra_timing |= 0x45;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_3:
-			ultra_timing |= 0x44;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_2:
-			ultra_timing |= 0x40;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_1:
-			ultra_timing |= 0x41;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_0:
-			ultra_timing |= 0x42;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_MW_DMA_2:
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_MW_DMA_1:
-			dma_pio_timing |= 0x21;
-			break;
-		case XFER_MW_DMA_0:
-			dma_pio_timing |= 0x77;
-			break;
-		case XFER_SW_DMA_2:
-			if (!amd74xx_swdma_check(dev))
-				return amd74xx_swdma_error(drive);
-			dma_pio_timing |= 0x42;
-			break;
-		case XFER_SW_DMA_1:
-			if (!amd74xx_swdma_check(dev))
-				return amd74xx_swdma_error(drive);
-			dma_pio_timing |= 0x65;
-			break;
-		case XFER_SW_DMA_0:
-			if (!amd74xx_swdma_check(dev))
-				return amd74xx_swdma_error(drive);
-			dma_pio_timing |= 0xA8;
-			break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-		case XFER_PIO_4:
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_PIO_3:
-			dma_pio_timing |= 0x22;
-			break;
-		case XFER_PIO_2:
-			dma_pio_timing |= 0x42;
-			break;
-		case XFER_PIO_1:
-			dma_pio_timing |= 0x65;
-			break;
-		case XFER_PIO_0:
-		default:
-			dma_pio_timing |= 0xA8;
-			break;
-        }
+	amd_print("-------------------drive0----drive1----drive2----drive3-----");
 
-	pio_timing |= (0x03 << drive->dn);
+	pci_read_config_byte(dev, AMD_ADDRESS_SETUP, &t);
+	pci_read_config_dword(dev, AMD_DRIVE_TIMING, &v);
+	pci_read_config_word(dev, AMD_8BIT_TIMING, &w);
+	pci_read_config_dword(dev, AMD_UDMA_TIMING, &u);
 
-	if (!drive->init_speed)
-		drive->init_speed = speed;
+	for (i = 0; i < 4; i++) {
+		setup[i]     = ((t >> ((3 - i) << 1)) & 0x3) + 1;
+		recover8b[i] = ((w >> ((1 - (i >> 1)) << 3)) & 0xf) + 1;
+		active8b[i]  = ((w >> (((1 - (i >> 1)) << 3) + 4)) & 0xf) + 1;
+		active[i]    = ((v >> (((3 - i) << 3) + 4)) & 0xf) + 1;
+		recover[i]   = ((v >> ((3 - i) << 3)) & 0xf) + 1;
 
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	pci_write_config_byte(dev, drive_pci, ultra_timing);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-	pci_write_config_byte(dev, drive_pci2, dma_pio_timing);
-	pci_write_config_byte(dev, 0x4c, pio_timing);
+		udma[i] = amd_udma2cyc[((u >> ((3 - i) << 3)) & 0x7)];
+		uen[i]  = ((u >> ((3 - i) << 3)) & 0x40) ? 1 : 0;
+		den[i]  = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
+
+		if (den[i] && uen[i] && udma[i] == 1) {
+			speed[i] = amd_clock * 3;
+			cycle[i] = 666666 / amd_clock;
+			continue;
+		}
+
+		speed[i] = 4 * amd_clock / ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2);
+		cycle[i] = 1000000 * ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2) / amd_clock / 2;
+	}
+
+	amd_print_drive("Transfer Mode: ", "%10s", den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
+
+	amd_print_drive("Address Setup: ", "%8dns", 1000000 * setup[i] / amd_clock);
+	amd_print_drive("Cmd Active:    ", "%8dns", 1000000 * active8b[i] / amd_clock);
+	amd_print_drive("Cmd Recovery:  ", "%8dns", 1000000 * recover8b[i] / amd_clock);
+	amd_print_drive("Data Active:   ", "%8dns", 1000000 * active[i] / amd_clock);
+	amd_print_drive("Data Recovery: ", "%8dns", 1000000 * recover[i] / amd_clock);
+	amd_print_drive("Cycle Time:    ", "%8dns", cycle[i]);
+	amd_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10);
+
+	return p - buffer;	/* hoping it is less than 4K... */
+}
 
-#ifdef DEBUG
-	printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
-		drive->name, ultra_timing, dma_pio_timing, pio_timing);
 #endif
 
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	if (speed > XFER_PIO_4) {
-		outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
-	} else {
-		outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
+/*
+ * amd_set_speed() writes timing values to the chipset registers
+ */
+
+static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timing *timing)
+{
+	unsigned char t;
+
+	pci_read_config_byte(dev, AMD_ADDRESS_SETUP, &t);
+	t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
+	pci_write_config_byte(dev, AMD_ADDRESS_SETUP, t);
+
+	pci_write_config_byte(dev, AMD_8BIT_TIMING + (1 - (dn >> 1)),
+		((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1));
+
+	pci_write_config_byte(dev, AMD_DRIVE_TIMING + (3 - dn),
+		((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
+
+	switch (amd_config->flags & AMD_UDMA) {
+		case AMD_UDMA_33:  t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
+		case AMD_UDMA_66:  t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break;
+		case AMD_UDMA_100: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break;
+		default: return;
 	}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
 
-	err = ide_config_drive_speed(drive, speed);
-	drive->current_speed = speed;
-	return (err);
+	pci_write_config_byte(dev, AMD_UDMA_TIMING + (3 - dn), t);
 }
 
-static void config_chipset_for_pio (ide_drive_t *drive)
+/*
+ * amd_set_drive() computes timing values configures the drive and
+ * the chipset to a desired transfer mode. It also can be called
+ * by upper layers.
+ */
+
+static int amd_set_drive(ide_drive_t *drive, unsigned char speed)
 {
-	unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
-	unsigned short xfer_pio	= drive->id->eide_pio_modes;
-	byte			timing, speed, pio;
-
-	pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
-
-	if (xfer_pio> 4)
-		xfer_pio = 0;
-
-	if (drive->id->eide_pio_iordy > 0) {
-		for (xfer_pio = 5;
-			xfer_pio>0 &&
-			drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
-			xfer_pio--);
-	} else {
-		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-			   (drive->id->eide_pio_modes & 2) ? 0x04 :
-			   (drive->id->eide_pio_modes & 1) ? 0x03 :
-			   (drive->id->tPIO & 2) ? 0x02 :
-			   (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
-	}
-
-	timing = (xfer_pio >= pio) ? xfer_pio : pio;
-
-	switch(timing) {
-		case 4: speed = XFER_PIO_4;break;
-		case 3: speed = XFER_PIO_3;break;
-		case 2: speed = XFER_PIO_2;break;
-		case 1: speed = XFER_PIO_1;break;
-		default:
-			speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
-			break;
+	ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
+	struct ide_timing t, p;
+	int T, UT;
+
+	if (speed != XFER_PIO_SLOW && speed != drive->current_speed)
+		if (ide_config_drive_speed(drive, speed))
+			printk(KERN_WARNING "ide%d: Drive %d didn't accept speed setting. Oh, well.\n",
+				drive->dn >> 1, drive->dn & 1);
+
+	T = 1000000000 / amd_clock;
+	UT = T / MIN(MAX(amd_config->flags & AMD_UDMA, 1), 2);
+
+	ide_timing_compute(drive, speed, &t, T, UT);
+
+	if (peer->present) {
+		ide_timing_compute(peer, peer->current_speed, &p, T, UT);
+		ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
 	}
-	(void) amd74xx_tune_chipset(drive, speed);
+
+	if (speed == XFER_UDMA_5 && amd_clock <= 33333) t.udma = 1;
+
+	amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
+
+	if (!drive->init_speed)	
+		drive->init_speed = speed;
 	drive->current_speed = speed;
+
+	return 0;
 }
 
-static void amd74xx_tune_drive (ide_drive_t *drive, byte pio)
+/*
+ * amd74xx_tune_drive() is a callback from upper layers for
+ * PIO-only tuning.
+ */
+
+static void amd74xx_tune_drive(ide_drive_t *drive, unsigned char pio)
 {
-	byte speed;
-	switch(pio) {
-		case 4:		speed = XFER_PIO_4;break;
-		case 3:		speed = XFER_PIO_3;break;
-		case 2:		speed = XFER_PIO_2;break;
-		case 1:		speed = XFER_PIO_1;break;
-		default:	speed = XFER_PIO_0;break;
+	if (!((amd_enabled >> HWIF(drive)->channel) & 1))
+		return;
+
+	if (pio == 255) {
+		amd_set_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO));
+		return;
 	}
-	(void) amd74xx_tune_chipset(drive, speed);
+
+	amd_set_drive(drive, XFER_PIO_0 + MIN(pio, 5));
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
+
 /*
- * This allows the configuration of ide_pci chipset registers
- * for cards that learn about the drive's UDMA, DMA, PIO capabilities
- * after the drive is reported by the OS.
+ * amd74xx_dmaproc() is a callback from upper layers that can do
+ * a lot, but we use it for DMA/PIO tuning only, delegating everything
+ * else to the default ide_dmaproc().
  */
-static int config_chipset_for_dma (ide_drive_t *drive)
+
+int amd74xx_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	struct hd_driveid *id	= drive->id;
-	byte udma_66		= eighty_ninty_three(drive);
-	byte udma_100		= ((dev->device==PCI_DEVICE_ID_AMD_VIPER_7411)||
-				   (dev->device==PCI_DEVICE_ID_AMD_VIPER_7441)) ? 1 : 0;
-	byte speed		= 0x00;
-	int  rval;
-
-	if ((id->dma_ultra & 0x0020) && (udma_66) && (udma_100)) {
-		speed = XFER_UDMA_5;
-	} else if ((id->dma_ultra & 0x0010) && (udma_66)) {
-		speed = XFER_UDMA_4;
-	} else if ((id->dma_ultra & 0x0008) && (udma_66)) {
-		speed = XFER_UDMA_3;
-	} else if (id->dma_ultra & 0x0004) {
-		speed = XFER_UDMA_2;
-	} else if (id->dma_ultra & 0x0002) {
-		speed = XFER_UDMA_1;
-	} else if (id->dma_ultra & 0x0001) {
-		speed = XFER_UDMA_0;
-	} else if (id->dma_mword & 0x0004) {
-		speed = XFER_MW_DMA_2;
-	} else if (id->dma_mword & 0x0002) {
-		speed = XFER_MW_DMA_1;
-	} else if (id->dma_mword & 0x0001) {
-		speed = XFER_MW_DMA_0;
-	} else {
-		return ((int) ide_dma_off_quietly);
-	}
-
-	(void) amd74xx_tune_chipset(drive, speed);
-
-	rval = (int)(	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
 
-	return rval;
+	if (func == ide_dma_check) {
+
+		short w80 = HWIF(drive)->udma_four;
+
+		short speed = ide_find_best_mode(drive,
+			XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA |
+			((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) |
+			(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) |
+			(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0));
+
+		amd_set_drive(drive, speed);
+
+		func = (HWIF(drive)->autodma && (speed & XFER_MODE) != XFER_PIO)
+			? ide_dma_on : ide_dma_off_quietly;
+	}
+
+	return ide_dmaproc(func, drive);
 }
 
-static int config_drive_xfer_rate (ide_drive_t *drive)
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+
+/*
+ * The initialization callback. Here we determine the IDE chip type
+ * and initialize its drive independent registers.
+ */
+
+unsigned int __init pci_init_amd74xx(struct pci_dev *dev, const char *name)
 {
-	struct hd_driveid *id = drive->id;
-	ide_dma_action_t dma_func = ide_dma_on;
+	unsigned char t;
+	unsigned int u;
+	int i;
 
-	if (id && (id->capability & 1) && HWIF(drive)->autodma) {
-		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
-			dma_func = ide_dma_off;
-			goto fast_ata_pio;
-		}
-		dma_func = ide_dma_off_quietly;
-		if (id->field_valid & 4) {
-			if (id->dma_ultra & 0x003F) {
-				/* Force if Capable UltraDMA */
-				dma_func = config_chipset_for_dma(drive);
-				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
-					goto try_dma_modes;
-			}
-		} else if (id->field_valid & 2) {
-try_dma_modes:
-			if ((id->dma_mword & 0x0007) ||
-			    ((id->dma_1word & 0x007) &&
-			     (amd74xx_swdma_check(HWIF(drive)->pci_dev)))) {
-				/* Force if Capable regular DMA modes */
-				dma_func = config_chipset_for_dma(drive);
-				if (dma_func != ide_dma_on)
-					goto no_dma_set;
-			}
-			
-		} else if (ide_dmaproc(ide_dma_good_drive, drive)) {
-			if (id->eide_dma_time > 150) {
-				goto no_dma_set;
-			}
-			/* Consult the list of known "good" drives */
-			dma_func = config_chipset_for_dma(drive);
-			if (dma_func != ide_dma_on)
-				goto no_dma_set;
-		} else {
-			goto fast_ata_pio;
+/*
+ * Find out what AMD IDE is this.
+ */
+
+	for (amd_config = amd_ide_chips; amd_config->id; amd_config++) {
+			pci_read_config_byte(dev, PCI_REVISION_ID, &t);
+			if (dev->device == amd_config->id && t >= amd_config->rev)
+				break;
 		}
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
-no_dma_set:
 
-		config_chipset_for_pio(drive);
+	if (!amd_config->id) {
+		printk(KERN_WARNING "AMD_IDE: Unknown AMD IDE Chip, contact Vojtech Pavlik <vojtech@ucw.cz>\n");
+		return -ENODEV;
 	}
-	return HWIF(drive)->dmaproc(dma_func, drive);
-}
 
 /*
- * amd74xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
+ * Check 80-wire cable presence.
  */
 
-int amd74xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
-{
-	switch (func) {
-		case ide_dma_check:
-			return config_drive_xfer_rate(drive);
-		default:
+	switch (amd_config->flags & AMD_UDMA) {
+
+		case AMD_UDMA_100:
+			pci_read_config_byte(dev, AMD_CABLE_DETECT, &t);
+			amd_80w = ((u & 0x3) ? 1 : 0) | ((u & 0xc) ? 2 : 0);
+			for (i = 24; i >= 0; i -= 8)
+				if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) {
+					printk(KERN_WARNING "AMD_IDE: Bios didn't set cable bits corectly. Enabling workaround.\n");
+					amd_80w |= (1 << (1 - (i >> 4)));
+				}
+			break;
+
+		case AMD_UDMA_66:
+			pci_read_config_dword(dev, AMD_UDMA_TIMING, &u);
+			for (i = 24; i >= 0; i -= 8)
+				if ((u >> i) & 4)
+					amd_80w |= (1 << (1 - (i >> 4)));
 			break;
 	}
-	return ide_dmaproc(func, drive);	/* use standard DMA stuff */
-}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
 
-unsigned int __init pci_init_amd74xx(struct pci_dev *dev)
-{
-	unsigned long fixdma_base = pci_resource_start(dev, 4);
+	pci_read_config_dword(dev, AMD_IDE_ENABLE, &u);
+	amd_enabled = ((u & 1) ? 2 : 0) | ((u & 2) ? 1 : 0);
 
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	if (!amd74xx_swdma_check(dev))
-		printk("%s: disabling single-word DMA support (revision < C4)\n", dev->name);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+/*
+ * Take care of prefetch & postwrite.
+ */
 
-	if (!fixdma_base) {
-		/*
-		 *
-		 */
-	} else {
-		/*
-		 * enable DMA capable bit, and "not" simplex only
-		 */
-		outb(inb(fixdma_base+2) & 0x60, fixdma_base+2);
+	pci_read_config_byte(dev, AMD_IDE_CONFIG, &t);
+	pci_write_config_byte(dev, AMD_IDE_CONFIG,
+		(amd_config->flags & AMD_BAD_FIFO) ? (t & 0x0f) : (t | 0xf0));
 
-		if (inb(fixdma_base+2) & 0x80)
-			printk("%s: simplex device: DMA will fail!!\n", dev->name);
+/*
+ * Determine the system bus clock.
+ */
+
+	amd_clock = system_bus_speed * 1000;
+
+	switch (amd_clock) {
+		case 33000: amd_clock = 33333; break;
+		case 37000: amd_clock = 37500; break;
+		case 41000: amd_clock = 41666; break;
 	}
-#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS)
+
+	if (amd_clock < 20000 || amd_clock > 50000) {
+		printk(KERN_WARNING "AMD_IDE: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", amd_clock);
+		printk(KERN_WARNING "AMD_IDE: Use ide0=ata66 if you want to assume 80-wire cable\n");
+		amd_clock = 33333;
+	}
+
+/*
+ * Print the boot message.
+ */
+
+	pci_read_config_byte(dev, PCI_REVISION_ID, &t);
+	printk(KERN_INFO "AMD_IDE: AMD-%s (rev %02x) IDE %s controller on pci%s\n",
+		amd_config->name, t, amd_dma[amd_config->flags & AMD_UDMA], dev->slot_name);
+
+/*
+ * Register /proc/ide/amd74xx entry
+ */
+
+#ifdef CONFIG_PROC_FS
 	if (!amd74xx_proc) {
-		amd74xx_proc = 1;
+		amd_base = pci_resource_start(dev, 4);
 		bmide_dev = dev;
-		amd74xx_display_info = &amd74xx_get_info;
+		amd74xx_display_info = &amd_get_info;
+		amd74xx_proc = 1;
 	}
-#endif /* DISPLAY_VIPER_TIMINGS && CONFIG_PROC_FS */
+#endif
 
 	return 0;
 }
 
-unsigned int __init ata66_amd74xx (ide_hwif_t *hwif)
+unsigned int __init ata66_amd74xx(ide_hwif_t *hwif)
 {
-#ifdef CONFIG_AMD74XX_OVERRIDE
-	byte ata66 = 1;
-#else
-	byte ata66 = 0;
-#endif /* CONFIG_AMD74XX_OVERRIDE */
-
-#if 0
-	pci_read_config_byte(hwif->pci_dev, 0x48, &ata66);
-	return ((ata66 & 0x02) ? 0 : 1);
-#endif
-	return ata66;
+	return ((amd_enabled & amd_80w) >> hwif->channel) & 1;
 }
 
-void __init ide_init_amd74xx (ide_hwif_t *hwif)
+void __init ide_init_amd74xx(ide_hwif_t *hwif)
 {
-	hwif->tuneproc = &amd74xx_tune_drive;
-	hwif->speedproc = &amd74xx_tune_chipset;
+	int i;
 
-	hwif->highmem = 1;
-
-#ifndef CONFIG_BLK_DEV_IDEDMA
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->tuneproc = &amd74xx_tune_drive;
+	hwif->speedproc = &amd_set_drive;
 	hwif->autodma = 0;
-	return;
-#else
 
+	for (i = 0; i < 2; i++) {
+		hwif->drives[i].io_32bit = 1;
+		hwif->drives[i].unmask = 1;
+		hwif->drives[i].autotune = 1;
+		hwif->drives[i].dn = hwif->channel * 2 + i;
+	}
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_base) {
+		hwif->highmem = 1;
 		hwif->dmaproc = &amd74xx_dmaproc;
+#ifdef CONFIG_IDEDMA_AUTO
 		if (!noautodma)
 			hwif->autodma = 1;
-	} else {
-		hwif->autodma = 0;
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
+#endif
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 }
 
-void __init ide_dmacapable_amd74xx (ide_hwif_t *hwif, unsigned long dmabase)
+/*
+ * We allow the BM-DMA driver only work on enabled interfaces.
+ */
+
+void __init ide_dmacapable_amd74xx(ide_hwif_t *hwif, unsigned long dmabase)
 {
-	ide_setup_dma(hwif, dmabase, 8);
+	if ((amd_enabled >> hwif->channel) & 1)
+		ide_setup_dma(hwif, dmabase, 8);
 }
diff -urN linux-2.5.6/drivers/ide/ide-pci.c linux-2.5.6-amdide/drivers/ide/ide-pci.c
--- linux-2.5.6/drivers/ide/ide-pci.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-amdide/drivers/ide/ide-pci.c	Mon Mar 11 15:57:33 2002
@@ -284,10 +284,11 @@
 	{PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE, pci_init_cs5530, NULL, ide_init_cs5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, ATA_F_DMA },
 #endif
 #ifdef CONFIG_BLK_DEV_AMD74XX
-	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401, NULL, NULL, NULL, ide_dmacapable_amd74xx, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401, pci_init_amd74xx, ata66_amd74xx, ide_init_amd74xx, ide_dmacapable_amd74xx, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0, 0 },
 	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409, pci_init_amd74xx, ata66_amd74xx, ide_init_amd74xx, ide_dmacapable_amd74xx, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0, 0 },
 	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411, pci_init_amd74xx, ata66_amd74xx, ide_init_amd74xx, ide_dmacapable_amd74xx, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0, 0 },
-	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7441, pci_init_amd74xx, ata66_amd74xx, ide_init_amd74xx, ide_dmacapable_amd74xx, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441, pci_init_amd74xx, ata66_amd74xx, ide_init_amd74xx, ide_dmacapable_amd74xx, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, pci_init_amd74xx, ata66_amd74xx, ide_init_amd74xx, ide_dmacapable_amd74xx, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0, 0 },
 #endif
 #ifdef CONFIG_BLK_DEV_PDC_ADMA
 	{PCI_VENDOR_ID_PDC, PCI_DEVICE_ID_PDC_1841, pci_init_pdcadma, ata66_pdcadma, ide_init_pdcadma, ide_dmacapable_pdcadma, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_NODMA },
diff -urN linux-2.5.6/include/linux/pci_ids.h linux-2.5.6-amdide/include/linux/pci_ids.h
--- linux-2.5.6/include/linux/pci_ids.h	Mon Mar 11 08:46:23 2002
+++ linux-2.5.6-amdide/include/linux/pci_ids.h	Mon Mar 11 15:48:59 2002
@@ -383,11 +383,14 @@
 #define PCI_DEVICE_ID_AMD_VIPER_7411	0x7411
 #define PCI_DEVICE_ID_AMD_VIPER_7413	0x7413
 #define PCI_DEVICE_ID_AMD_VIPER_7414	0x7414
-#define PCI_DEVICE_ID_AMD_VIPER_7440	0x7440
-#define PCI_DEVICE_ID_AMD_VIPER_7441	0x7441
-#define PCI_DEVICE_ID_AMD_VIPER_7443	0x7443
-#define PCI_DEVICE_ID_AMD_VIPER_7448	0x7448
-#define PCI_DEVICE_ID_AMD_VIPER_7449	0x7449
+#define PCI_DEVICE_ID_AMD_OPUS_7440	0x7440
+#define PCI_DEVICE_ID_AMD_OPUS_7441	0x7441
+#define PCI_DEVICE_ID_AMD_OPUS_7443	0x7443
+#define PCI_DEVICE_ID_AMD_OPUS_7448	0x7448
+#define PCI_DEVICE_ID_AMD_OPUS_7449	0x7449
+#define PCI_DEVICE_ID_AMD_8111_LAN	0x7462
+#define PCI_DEVICE_ID_AMD_8111_IDE	0x7469
+#define PCI_DEVICE_ID_AMD_8111_AUDIO	0x746d
 
 #define PCI_VENDOR_ID_TRIDENT		0x1023
 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX	0x2000

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-11 15:13 [patch] My AMD IDE driver, v2.7 Vojtech Pavlik
@ 2002-03-11 16:36 ` Martin Dalecki
  2002-03-11 20:49   ` Rik van Riel
  0 siblings, 1 reply; 107+ messages in thread
From: Martin Dalecki @ 2002-03-11 16:36 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Martin Dalecki, Linus Torvalds, LKML

Vojtech Pavlik wrote:
> Hi!
> 
> This patch replaces the current AMD IDE driver (by Andre Hedrick) by
> mine. Myself I think my implementation is much cleaner, but I'll leave
> upon others to judge that. My driver also additionally supports the
> AMD-8111 IDE.
> 
> It's well tested, and I'd like to have this in the kernel instead of
> what's there now.

Agreed. Let's give it a try. (This is trivial to back up.)


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  1:50                       ` Jeff Garzik
@ 2002-03-11 18:50                         ` gmack
  2002-03-12  2:19                         ` Linus Torvalds
  2002-03-13 18:42                         ` Horst von Brand
  2 siblings, 0 replies; 107+ messages in thread
From: gmack @ 2002-03-11 18:50 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Linus Torvalds, andersen, Bill Davidsen, LKML

> I -do- know the distrinction between hosts and devices.  I think there 
> should be -some- way, I don't care how, to filter out those unknown 
> commands (which may be perfectly valid for a small subset of special IBM 
> drives).  The net stack lets me do filtering, I want to sell you on the 
> idea of letting the ATA stack do the same thing.
> 
> You have convinced me that unconditional filtering is bad.  But I still 
> think people should be provided the option to filter if they so desire.
> 
>     Jeff

How hard would this be to farm off to an external utility?

	Gerhard



--
Gerhard Mack

gmack@innerfire.net

<>< As a computer I find your faith in technology amusing.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-11 16:36 ` Martin Dalecki
@ 2002-03-11 20:49   ` Rik van Riel
  2002-03-11 22:45     ` Alan Cox
  0 siblings, 1 reply; 107+ messages in thread
From: Rik van Riel @ 2002-03-11 20:49 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Vojtech Pavlik, Martin Dalecki, Linus Torvalds, LKML

On Mon, 11 Mar 2002, Martin Dalecki wrote:
> Vojtech Pavlik wrote:

> > This patch replaces the current AMD IDE driver (by Andre Hedrick) by
> > mine.

> Agreed. Let's give it a try. (This is trivial to back up.)

I think experience has tought us by now that large changes in
code are impossible to completely back out or debug.

Then again, after reading your discussion with Alan I guess
we don't have much too lose anyway.

regards,

Rik
-- 
<insert bitkeeper endorsement here>

http://www.surriel.com/		http://distro.conectiva.com/


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-11 22:45     ` Alan Cox
@ 2002-03-11 22:39       ` Linus Torvalds
  2002-03-11 22:45         ` Vojtech Pavlik
  2002-03-11 23:01         ` [patch] My AMD IDE driver, v2.7 Alan Cox
  0 siblings, 2 replies; 107+ messages in thread
From: Linus Torvalds @ 2002-03-11 22:39 UTC (permalink / raw)
  To: Alan Cox
  Cc: Rik van Riel, Martin Dalecki, Vojtech Pavlik, Martin Dalecki, LKML


On Mon, 11 Mar 2002, Alan Cox wrote:
> 
> Its quite different to other goings on

Alan, did you actually look at the diffs that Martin sent out, or are you 
just reacting to the description?

I think you read more into the description than was actually in the patch 
itself.

Rule #1: always read the patch.

Right now, that patch definitely needs to learn to use "yield()" instead
of "schedule()" etc details, but I really don't understand why all the 
brouhaha over Martins patches.

Am I really the only one who actually reads the actual _changes_ instead
of arguing over personal issues?

Now, I've long had this theory that IDE coding is bad for your mental
health (you won't ever see _me_ going close to the dang thing - I'll use
it, but I won't start writing code for it), but that theory used to be a
_joke_, for chrissake! Don't make it appear a truism.

			Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-11 20:49   ` Rik van Riel
@ 2002-03-11 22:45     ` Alan Cox
  2002-03-11 22:39       ` Linus Torvalds
  0 siblings, 1 reply; 107+ messages in thread
From: Alan Cox @ 2002-03-11 22:45 UTC (permalink / raw)
  To: Rik van Riel
  Cc: Martin Dalecki, Vojtech Pavlik, Martin Dalecki, Linus Torvalds, LKML

> > > This patch replaces the current AMD IDE driver (by Andre Hedrick) by
> > > mine.
> 
> > Agreed. Let's give it a try. (This is trivial to back up.)
> 
> I think experience has tought us by now that large changes in
> code are impossible to completely back out or debug.

The AMD stuff is a nice seperate single driver update. It cleans up the
code a hell of a lot and adds new stuff. I'll run it into -ac later for
testing.

Its quite different to other goings on


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-11 22:39       ` Linus Torvalds
@ 2002-03-11 22:45         ` Vojtech Pavlik
  2002-03-11 22:53           ` Linus Torvalds
  2002-03-12 11:00           ` Martin Dalecki
  2002-03-11 23:01         ` [patch] My AMD IDE driver, v2.7 Alan Cox
  1 sibling, 2 replies; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-11 22:45 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Alan Cox, Rik van Riel, Martin Dalecki, Vojtech Pavlik,
	Martin Dalecki, LKML

On Mon, Mar 11, 2002 at 02:39:14PM -0800, Linus Torvalds wrote:

> On Mon, 11 Mar 2002, Alan Cox wrote:
> > 
> > Its quite different to other goings on
> 
> Alan, did you actually look at the diffs that Martin sent out, or are you 
> just reacting to the description?
> 
> I think you read more into the description than was actually in the patch 
> itself.
> 
> Rule #1: always read the patch.
> 
> Right now, that patch definitely needs to learn to use "yield()" instead
> of "schedule()" etc details, but I really don't understand why all the 
> brouhaha over Martins patches.
> 
> Am I really the only one who actually reads the actual _changes_ instead
> of arguing over personal issues?
> 
> Now, I've long had this theory that IDE coding is bad for your mental
> health (you won't ever see _me_ going close to the dang thing - I'll use
> it, but I won't start writing code for it), but that theory used to be a
> _joke_, for chrissake! Don't make it appear a truism.

Are you, by any chance, confusing my AMD IDE changes with Pavel Machek's
first attempt at IDE wake/suspend code?

Gee, I think we all need some calming down and sleep ...

-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-11 22:45         ` Vojtech Pavlik
@ 2002-03-11 22:53           ` Linus Torvalds
  2002-03-12  0:14             ` Bill Davidsen
  2002-03-12 11:00           ` Martin Dalecki
  1 sibling, 1 reply; 107+ messages in thread
From: Linus Torvalds @ 2002-03-11 22:53 UTC (permalink / raw)
  To: Vojtech Pavlik
  Cc: Alan Cox, Rik van Riel, Martin Dalecki, Martin Dalecki, LKML


On Mon, 11 Mar 2002, Vojtech Pavlik wrote:
> 
> Are you, by any chance, confusing my AMD IDE changes with Pavel Machek's
> first attempt at IDE wake/suspend code?

No, I'm just reacting to alan's email where he mentions the "other goings 
on" - as opposed to your patch which even Alan agreed with.

Note that I've actually tried to read all patches, and right now they are 
all in my tree (of course, the "all" is the Linus kind of "all", which 
only includes the ones I actually _noticed_. 

That includes your AMD IDE driver change _and_ the oh-so-much-discussed
patches by Martin (which in turn included Pavel's change, which - together
with his changelog entry - seems to be the one that triggered the "lively
discussions").

		Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-11 22:39       ` Linus Torvalds
  2002-03-11 22:45         ` Vojtech Pavlik
@ 2002-03-11 23:01         ` Alan Cox
  1 sibling, 0 replies; 107+ messages in thread
From: Alan Cox @ 2002-03-11 23:01 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Alan Cox, Rik van Riel, Martin Dalecki, Vojtech Pavlik,
	Martin Dalecki, LKML

> On Mon, 11 Mar 2002, Alan Cox wrote:
> > 
> > Its quite different to other goings on
> 
> Alan, did you actually look at the diffs that Martin sent out, or are you 
> just reacting to the description?

I wasnt actually trying to be rude there. Just make it clear that the AMD
stuff is seperate and quite reasonable 2.4 stuff while the big changes
are 2.5 stuff

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-11 22:53           ` Linus Torvalds
@ 2002-03-12  0:14             ` Bill Davidsen
  2002-03-12  0:34               ` Jeff Garzik
  2002-03-12  0:51               ` Linus Torvalds
  0 siblings, 2 replies; 107+ messages in thread
From: Bill Davidsen @ 2002-03-12  0:14 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: LKML

On Mon, 11 Mar 2002, Linus Torvalds wrote:

> Note that I've actually tried to read all patches, and right now they are 
> all in my tree (of course, the "all" is the Linus kind of "all", which 
> only includes the ones I actually _noticed_. 
> 
> That includes your AMD IDE driver change _and_ the oh-so-much-discussed
> patches by Martin (which in turn included Pavel's change, which - together
> with his changelog entry - seems to be the one that triggered the "lively
> discussions").

I think you might want to offer an opinion (or edict, mandate, whatever)
WRT taskfile. While I think that some protective editing of commands is
desirable, useful, etc, I'm damn sure that some form of raw access is
required long term to allow diagmostics. I wouldn't argue if that
interface was required for low level format and other really drastic
operations as well.

I think "future new commands" is total FUD, the idea that some new command
would come along and be so instantly popular, useful and incompatible that
all Linux boxes would require it before the next kernel or driver update
is silly at best, and I'm working hard to keep this on a civil plane.
Linux moves a hell of a lot faster than Windows, and I can't see anything
coming out which requires "instant attention" because it is totally
incompatible with existing drivers. Most changes will be only added
functionality, like 48 bit addressing, and will be a superset of current
drivers. In other words, not everyone will wnat or need the capability,
and no one is going to feel that a month or so wait from driver TESTING
would cause them to give up computing and become a stripper in a gay bar.

In any case, taskfile is here, and unless there is a good reason to drop
lightly edited commands, or raw commands, or go to some totally different
approach, I wish you would express a clear opinion, at least WRT 2.4,
before developers become nasty and stop limiting themselves to accusations
of stupidity, incompetence, inreliability and prevarication.

-- 
bill davidsen <davidsen@tmr.com>
  CTO, TMR Associates, Inc
Doing interesting things with little computers since 1979.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 11:10                   ` [patch] My AMD IDE driver, v2.7 Martin Dalecki
@ 2002-03-12  0:33                     ` benh
  0 siblings, 0 replies; 107+ messages in thread
From: benh @ 2002-03-12  0:33 UTC (permalink / raw)
  To: Martin Dalecki, Jeff Garzik; +Cc: Linus Torvalds, Bill Davidsen, LKML

>> Linus, would it be acceptable to you to include an -optional- filter for 
>> ATA commands?  There is definitely a segment of users that would like to 
>> firewall their devices, and I think (as crazy as it may sound) that 
>> notion is a valid one.
>
>If you are *trully paranoid* and want to *fire wall* your device then
>the proper way of doing this is to DISABLE those ioctl entierly.
>It simple like that. They are not required for regular operation by
>concept. Other then this I see no argument here.

Well; I don't agree. Firewall via a loadable module can make sense if the
actual module does a kind of "filter all but a specified known set of safe
commands" for example, like retreiving SMART infos, or such things.

Ben.




^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  0:14             ` Bill Davidsen
@ 2002-03-12  0:34               ` Jeff Garzik
  2002-03-12  0:58                 ` Erik Andersen
  2002-03-12 16:40                 ` Bill Davidsen
  2002-03-12  0:51               ` Linus Torvalds
  1 sibling, 2 replies; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  0:34 UTC (permalink / raw)
  To: Bill Davidsen; +Cc: Linus Torvalds, LKML

Bill Davidsen wrote:

>On Mon, 11 Mar 2002, Linus Torvalds wrote:
>
>>Note that I've actually tried to read all patches, and right now they are 
>>all in my tree (of course, the "all" is the Linus kind of "all", which 
>>only includes the ones I actually _noticed_. 
>>
>>That includes your AMD IDE driver change _and_ the oh-so-much-discussed
>>patches by Martin (which in turn included Pavel's change, which - together
>>with his changelog entry - seems to be the one that triggered the "lively
>>discussions").
>>
>
>I think you might want to offer an opinion (or edict, mandate, whatever)
>WRT taskfile. While I think that some protective editing of commands is
>desirable, useful, etc, I'm damn sure that some form of raw access is
>required long term to allow diagmostics. I wouldn't argue if that
>interface was required for low level format and other really drastic
>operations as well.
>
One sticking point seems to be the question of whether there needs to be 
some amount of validation performed on the commands passed through the 
taskfile interface.  I don't think Andre buys into the argument that 
most other kernel hackers understand, which is, "if userspace is allowed 
to bang away at random i/o ports, why validate taskfile  requests in the 
kernel?"

And IMO, we should have some basic validation of taskfile requests in 
the kernel...
Reason 1: Standard kernel convention.  In other ioctls, we check basic 
arguments and return EINVAL when they are wrong, even for privieleged 
ioctls.
Reason 2: If you have multiple programs issuing ATA commands, you would 
want a decent amount of synchronization, provided by the kernel, for the 
multiple user processes and multiple kernel processes issuing requests. 
 Having the userspace commands come down a single spot in the kernel 
code makes this job a lot easier, if not making the impossible possible :)

Regards,

    Jeff









^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  0:14             ` Bill Davidsen
  2002-03-12  0:34               ` Jeff Garzik
@ 2002-03-12  0:51               ` Linus Torvalds
  2002-03-12  1:41                 ` Jeff Garzik
  2002-03-12 16:33                 ` Bill Davidsen
  1 sibling, 2 replies; 107+ messages in thread
From: Linus Torvalds @ 2002-03-12  0:51 UTC (permalink / raw)
  To: Bill Davidsen; +Cc: LKML



On Mon, 11 Mar 2002, Bill Davidsen wrote:
>
> I think you might want to offer an opinion (or edict, mandate, whatever)
> WRT taskfile. While I think that some protective editing of commands is
> desirable, useful, etc, I'm damn sure that some form of raw access is
> required long term to allow diagmostics. I wouldn't argue if that
> interface was required for low level format and other really drastic
> operations as well.

Quite frankly, my personal opinion is that there's no point in trying to
parse the commands too much at all. The _only_ thing the kernel should try
to care about is that the buffers passed to the command are valid (ie the
actual data in/out area pointer should be a kernel buffer as far as
possible, not under user control).

Basically, there are three "modes" of operation here:

 - regular kernel access (ie the normal read/write stuff)

   parsing: none. The kernel originated the request.

 - common ioctl's that have nothing to do with IDE per se (ie all the
   stuff to open/close/lock removable media, unlocking DVD's, reading
   sound sectors etc - stuff that really exists elsewhere too, and where
   the kernel should do the translation from the generic problem space to
   the specific commands for the bus in quesion)

   Parsing: common ioctl turning stuff into common SCSI commands in the
   "struct request".

 - totally IDE-only stuff, where the kernel simply doesn't add any value,
   and only has a way of passing it down to the drive, and passing back
   the requests.

   Parsing: none. The kernel simply doesn't have anything to do with the
   request, except to synchronize it with all other requests.

The only common factor here is the "synchronize with other requests" - I
feel strongly (much more strongly than any parsing notion) that the raw
requests have to be passed down the "struct request" and NOT be done the
way they are traditionally done (ie completely outside the request stream,
with no synchronization at all with any IO currently in progress).

> I think "future new commands" is total FUD, the idea that some new command
> would come along and be so instantly popular, useful and incompatible that
> all Linux boxes would require it before the next kernel or driver update
> is silly at best, and I'm working hard to keep this on a civil plane.

It has nothing to do with "new" commands, and everything to do with
"random vendor-specific commands and the vendor-specific tools". Commands
that simply should _never_ be parsed in the kernel, because we do not want
to care about 10 different vendors 10 different revisions of their
firmware having 10 different small random special commands for that
particular drive.

In particular, a user that upgrades his hardware should never _ever_ have
to upgrade his kernel just because some random disk diagnostic tool needs
support for a disk that is new and has new diagnostics.

			Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  0:34               ` Jeff Garzik
@ 2002-03-12  0:58                 ` Erik Andersen
  2002-03-12  1:33                   ` Jeff Garzik
  2002-03-12  7:13                   ` Erik Andersen
  2002-03-12 16:40                 ` Bill Davidsen
  1 sibling, 2 replies; 107+ messages in thread
From: Erik Andersen @ 2002-03-12  0:58 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Bill Davidsen, Linus Torvalds, LKML

On Mon Mar 11, 2002 at 07:34:26PM -0500, Jeff Garzik wrote:
> Reason 1: Standard kernel convention.  In other ioctls, we check basic 
> arguments and return EINVAL when they are wrong, even for privieleged 
> ioctls.

I have no argument with basic command validation.  But take a
look at ide_cmd_type_parser(), for example.  Do we really need a
giant switch statement listing all the allowed commands, just so
we can throw back a IDE_DRIVE_TASK_INVALID to user-space if they
decide to send down some undocumeted firmware wiping commands?
Especially since that giant struct of allowed commands is
duplicated in ide_pre_handler_parser() and ide_handler_parser() 

 -Erik

--
Erik B. Andersen             http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  0:58                 ` Erik Andersen
@ 2002-03-12  1:33                   ` Jeff Garzik
  2002-03-12  1:41                     ` Linus Torvalds
  2002-03-12  6:25                     ` Vojtech Pavlik
  2002-03-12  7:13                   ` Erik Andersen
  1 sibling, 2 replies; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  1:33 UTC (permalink / raw)
  To: andersen; +Cc: Bill Davidsen, Linus Torvalds, LKML

Erik Andersen wrote:

>On Mon Mar 11, 2002 at 07:34:26PM -0500, Jeff Garzik wrote:
>
>>Reason 1: Standard kernel convention.  In other ioctls, we check basic 
>>arguments and return EINVAL when they are wrong, even for privieleged 
>>ioctls.
>>
>
>I have no argument with basic command validation.  But take a
>look at ide_cmd_type_parser(), for example.  Do we really need a
>giant switch statement listing all the allowed commands, just so
>we can throw back a IDE_DRIVE_TASK_INVALID to user-space if they
>decide to send down some undocumeted firmware wiping commands?
>Especially since that giant struct of allowed commands is
>duplicated in ide_pre_handler_parser() and ide_handler_parser()
>
I agree the implementation could be improved.

Your first question is really philosophical.  I think that people should 
-not- be able to send undocumented commands through the interface... 
 and in this area IMO it pays to be paranoid.

If we wanted to be ultra-super-paranoid, drop the ioctl and taskfile 
parser, and implement the taskfile checks via SMM mode callbacks from 
activity on the IDE ports ;-)  That way we know the NSA is not doing 
something sneaky, as well as supporting unlimited SMP bit-banging from 
userland.  Can you say ug and non-portable even to a lot of ia32 
platforms.  :)

So, the implementation may need improvement, but we do (a) want the 
taskfile ioctl [and one for scsi too], and (b) want to implement some 
amount of mininal sanity checks on the requests.

    Jeff






^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  1:33                   ` Jeff Garzik
@ 2002-03-12  1:41                     ` Linus Torvalds
  2002-03-12  1:50                       ` Jeff Garzik
  2002-03-12  6:25                     ` Vojtech Pavlik
  1 sibling, 1 reply; 107+ messages in thread
From: Linus Torvalds @ 2002-03-12  1:41 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: andersen, Bill Davidsen, LKML



On Mon, 11 Mar 2002, Jeff Garzik wrote:
>
> Your first question is really philosophical.  I think that people should
> -not- be able to send undocumented commands through the interface...
>  and in this area IMO it pays to be paranoid.

What if the command is perfectly documented, but only for a certain class
of IBM disks?

Are you going to create a table of every disk out there, along with every
command it can do?

Remember: the kernel driver is a driver for the host controller, yet the
command is for the _disk_. It makes no sense to check for disk commands in
a host controller driver - they are two different things.

It's like checking for icmp messages in a network driver. Do you seriously
propose having network drivers check icmp messages for command validity?

			Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  0:51               ` Linus Torvalds
@ 2002-03-12  1:41                 ` Jeff Garzik
  2002-03-12  1:44                   ` Linus Torvalds
                                     ` (3 more replies)
  2002-03-12 16:33                 ` Bill Davidsen
  1 sibling, 4 replies; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  1:41 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Bill Davidsen, LKML

Linus Torvalds wrote:

>The only common factor here is the "synchronize with other requests" - I
>feel strongly (much more strongly than any parsing notion) that the raw
>requests have to be passed down the "struct request" and NOT be done the
>way they are traditionally done (ie completely outside the request stream,
>with no synchronization at all with any IO currently in progress).
>
agreed

>>I think "future new commands" is total FUD, the idea that some new command
>>would come along and be so instantly popular, useful and incompatible that
>>all Linux boxes would require it before the next kernel or driver update
>>is silly at best, and I'm working hard to keep this on a civil plane.
>>
>
>It has nothing to do with "new" commands, and everything to do with
>"random vendor-specific commands and the vendor-specific tools". Commands
>that simply should _never_ be parsed in the kernel, because we do not want
>to care about 10 different vendors 10 different revisions of their
>firmware having 10 different small random special commands for that
>particular drive.
>
>In particular, a user that upgrades his hardware should never _ever_ have
>to upgrade his kernel just because some random disk diagnostic tool needs
>support for a disk that is new and has new diagnostics.
>
Are such random vendor-specific commands really that common?

Linus, would it be acceptable to you to include an -optional- filter for 
ATA commands?  There is definitely a segment of users that would like to 
firewall their devices, and I think (as crazy as it may sound) that 
notion is a valid one.

    Jeff






^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  1:41                 ` Jeff Garzik
@ 2002-03-12  1:44                   ` Linus Torvalds
  2002-03-12  2:22                     ` Jeff Garzik
  2002-03-12  2:57                   ` Alan Cox
                                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 107+ messages in thread
From: Linus Torvalds @ 2002-03-12  1:44 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Bill Davidsen, LKML



On Mon, 11 Mar 2002, Jeff Garzik wrote:
>
> Linus, would it be acceptable to you to include an -optional- filter for
> ATA commands?  There is definitely a segment of users that would like to
> firewall their devices, and I think (as crazy as it may sound) that
> notion is a valid one.

I'd rather have the rule that you can turn off this feature altogther: if
the command is so esoteric that it's not part of the regular commands we
can generate on our own, 99% of all people probably aren't even interested
in it.

If the command is useful on its own, and has a generic meaning (ie across
a large subset of users), then I think the kernel should support it
through a _real_ interface, not through some "pass user data though
inscathed" thing. Because that generic meaning probably exists even
outside ATA drives.

		Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  1:41                     ` Linus Torvalds
@ 2002-03-12  1:50                       ` Jeff Garzik
  2002-03-11 18:50                         ` gmack
                                           ` (2 more replies)
  0 siblings, 3 replies; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  1:50 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: andersen, Bill Davidsen, LKML

Linus Torvalds wrote:

>
>On Mon, 11 Mar 2002, Jeff Garzik wrote:
>
>>Your first question is really philosophical.  I think that people should
>>-not- be able to send undocumented commands through the interface...
>> and in this area IMO it pays to be paranoid.
>>
>
>What if the command is perfectly documented, but only for a certain class
>of IBM disks?
>
>Are you going to create a table of every disk out there, along with every
>command it can do?
>
>Remember: the kernel driver is a driver for the host controller, yet the
>command is for the _disk_. It makes no sense to check for disk commands in
>a host controller driver - they are two different things.
>
>It's like checking for icmp messages in a network driver. Do you seriously
>propose having network drivers check icmp messages for command validity?
>
See my other message, and thanks for making this analogy :)

I -do- know the distrinction between hosts and devices.  I think there 
should be -some- way, I don't care how, to filter out those unknown 
commands (which may be perfectly valid for a small subset of special IBM 
drives).  The net stack lets me do filtering, I want to sell you on the 
idea of letting the ATA stack do the same thing.

You have convinced me that unconditional filtering is bad.  But I still 
think people should be provided the option to filter if they so desire.

    Jeff






^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  1:50                       ` Jeff Garzik
  2002-03-11 18:50                         ` gmack
@ 2002-03-12  2:19                         ` Linus Torvalds
  2002-03-12  2:34                           ` Jeff Garzik
                                             ` (2 more replies)
  2002-03-13 18:42                         ` Horst von Brand
  2 siblings, 3 replies; 107+ messages in thread
From: Linus Torvalds @ 2002-03-12  2:19 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: andersen, Bill Davidsen, LKML



On Mon, 11 Mar 2002, Jeff Garzik wrote:
>
> You have convinced me that unconditional filtering is bad.  But I still
> think people should be provided the option to filter if they so desire.

Hey, choice is always good, except if it adds complexity.

The problem with conditional filtering is that either it is a boot (or
compile time) option, or it is a dynamic filter.

If its a dynamic filter, and you don't trust root, what _are_ you going to
trust? The root program you don't trust might as well be turning the
filtering off because it wants to be "convenient". And since the only
programs you really want to filter are _exactly_ the kinds of programs
that want to avoid filtering, you're just hosed.

That's my real beef with this whole idiotic parsing thing. Either it is
fixed (bad, if you don't know what the commands are for all disks) or it
is trivially overcome in the name of "convenience" (equally bad, since it
makes the whole thing pointless).

None of these issues really exist in your networking example.

Trust me, I'm not trying to be difficult, I'm just pointing out the
fundamental problems of your approach.

Yeah yeah. You can add additional levels of protection, and we have
capabilities.

Add a special password-protected capability, so that only YOU can enable
certain hardware access stuff. Where does it end? Is one such capability
enough? How do you initialize the default values for the system if you
need to be there to type in the password at bootup every time? We're
talking about some rather fundamental things here, and these are issues
that go _far_ beyond some silly ATA stack layer.

		Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  1:44                   ` Linus Torvalds
@ 2002-03-12  2:22                     ` Jeff Garzik
  2002-03-12  2:33                       ` Linus Torvalds
  2002-03-12  2:50                       ` J. Dow
  0 siblings, 2 replies; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  2:22 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Bill Davidsen, LKML

Linus Torvalds wrote:

>
>On Mon, 11 Mar 2002, Jeff Garzik wrote:
>
>>Linus, would it be acceptable to you to include an -optional- filter for
>>ATA commands?  There is definitely a segment of users that would like to
>>firewall their devices, and I think (as crazy as it may sound) that
>>notion is a valid one.
>>
>
>I'd rather have the rule that you can turn off this feature altogther: if
>the command is so esoteric that it's not part of the regular commands we
>can generate on our own, 99% of all people probably aren't even interested
>in it.
>
Are we talking about the same thing or different things?

If filtering is done, I agree the filter feature is disable-able if the 
kernel builder / sysadmin desires such.  Disable the filter by default, 
if that's your fancy.  But let us filter.  :)

>If the command is useful on its own, and has a generic meaning (ie across
>a large subset of users), then I think the kernel should support it
>through a _real_ interface, not through some "pass user data though
>inscathed" thing. Because that generic meaning probably exists even
>outside ATA drives.
>
Let me first agree on a point, to get that out of the way.  I agree 
there is generic meaning outside of ATA drives,for most of the ATA[PI] 
commands.  Further, I hope you know by now I agree with your taste in 
kernel interfaces :)

First, for verification of the driver, it's darned useful to be able to 
issue ATA commands from userspace.  But since we're being generic, let's 
just call them device commands, and imagine SCSI perhaps playing in this 
playground too.

Second, if you are issuing device commands from userspace, you need to 
deal with synchronization with the commands being issued from kernel space.

Third, if you have synchronization, that's a good and easy point to add 
-optional- filtering.

Now... the overall point I am trying to sell is...  IFF certain 
lesser-used device commands are primarily issued from userspace, and IFF 
it is not reasonable to create a new kernel interface, is it not 
reasonable to be able to issue raw device commands from userspace?  Just 
the verification case alone seems like a strong argument.

Call it device_command not ata_command if you want, and add SCSI 
support.  Passing in raw device_commands from userspace is useful, IMO. 
 Throw in filtering of those commands, and life is golden for everybody 
AFAICS.  There is no need to be ATA specific with these goals...

    Jeff




^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:22                     ` Jeff Garzik
@ 2002-03-12  2:33                       ` Linus Torvalds
  2002-03-12  2:37                         ` Jeff Garzik
  2002-03-12  2:50                       ` J. Dow
  1 sibling, 1 reply; 107+ messages in thread
From: Linus Torvalds @ 2002-03-12  2:33 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Bill Davidsen, LKML



On Mon, 11 Mar 2002, Jeff Garzik wrote:
>
> If filtering is done, I agree the filter feature is disable-able if the
> kernel builder / sysadmin desires such.  Disable the filter by default,
> if that's your fancy.  But let us filter.  :)

BUT WHAT THE HELL IS THE POINT?

Don't you get that? If the sysadmin can turn the filtering off, so can any
root program. And your worry seems to be the CRM kind of disk locking
utility which most _definitely_ would do exactly that if it is as evil as
you think it is.

And if you hardcode the filtering at compile-time in the kernel, that
means that you've now painted yourself into the corner that you already
seemed to admit was not a good idea - the same way it's not a good idea
for network filtering.

		Linus



^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:19                         ` Linus Torvalds
@ 2002-03-12  2:34                           ` Jeff Garzik
  2002-03-12 11:21                             ` Martin Dalecki
  2002-03-12  2:54                           ` J. Dow
  2002-03-12  6:32                           ` Vojtech Pavlik
  2 siblings, 1 reply; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  2:34 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: andersen, Bill Davidsen, LKML

Linus Torvalds wrote:

>
>On Mon, 11 Mar 2002, Jeff Garzik wrote:
>
>>You have convinced me that unconditional filtering is bad.  But I still
>>think people should be provided the option to filter if they so desire.
>>
>
>Hey, choice is always good, except if it adds complexity.
>
>The problem with conditional filtering is that either it is a boot (or
>compile time) option, or it is a dynamic filter.
>
heh, I couldn't have given a better argument against a dynamic filter.

I was actually assuming the filter would be a compile-time option, for 
security's sake.  Boot-time option works too.

So, it sounds like you could be sold on an fixed-at-compile-time filter 
that can be disabled at boot :)  I know you don't like 
fixed-at-compile-time as you mentioned, but it's my argument there is a 
class of users that definitely do.  MandrakeSoft would likely enable the 
filter in the "secure" kernel and disable it in the "normal" kernel, for 
example.

    Jeff







^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:33                       ` Linus Torvalds
@ 2002-03-12  2:37                         ` Jeff Garzik
  2002-03-12  3:34                           ` Olivier Galibert
  2002-03-12 11:23                           ` Martin Dalecki
  0 siblings, 2 replies; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  2:37 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Bill Davidsen, LKML

Linus Torvalds wrote:

>
>On Mon, 11 Mar 2002, Jeff Garzik wrote:
>
>>If filtering is done, I agree the filter feature is disable-able if the
>>kernel builder / sysadmin desires such.  Disable the filter by default,
>>if that's your fancy.  But let us filter.  :)
>>
>
>BUT WHAT THE HELL IS THE POINT?
>
>Don't you get that? If the sysadmin can turn the filtering off, so can any
>root program. And your worry seems to be the CRM kind of disk locking
>utility which most _definitely_ would do exactly that if it is as evil as
>you think it is.
>
dynamic filtering sucks, I agree, and I am not arguing for that.

>And if you hardcode the filtering at compile-time in the kernel, that
>means that you've now painted yourself into the corner that you already
>seemed to admit was not a good idea - the same way it's not a good idea
>for network filtering.
>
No, I think hardcoding at compile time is useful here.

It serves to encourage openness, nobody is forced to use it, and it 
provides an additional layer of protection for those that choose to use 
it.  That is the point.  It's a choice, and you don't have to enable it 
in your kernel.  But there seems to be enough demand that it should be 
at least an option.

    Jeff






^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:57                   ` Alan Cox
@ 2002-03-12  2:49                     ` Jeff Garzik
  2002-03-12 11:17                       ` Alan Cox
  2002-03-13  8:14                       ` ide filters / 'ide dump' / 'bio dump' bert hubert
  0 siblings, 2 replies; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  2:49 UTC (permalink / raw)
  To: Alan Cox; +Cc: Linus Torvalds, Bill Davidsen, LKML

Alan Cox wrote:

>>Linus, would it be acceptable to you to include an -optional- filter for 
>>ATA commands?  There is definitely a segment of users that would like to 
>>firewall their devices, and I think (as crazy as it may sound) that 
>>notion is a valid one.
>>
>
>Jeff -I like the idea of the filters - but if the ATA command raw stuff
>is CAP_SYS_RAWIO then its the same right set as inb/outb. Beyond that
>its a job for the NSA and RSBAC stuff ?
>
Yeah, you can still bit-bang with the current implementation, on that 
capability.  Couldn't that be cured with s/CAP_SYS_RAWIO/some new 
CAP_DEVICE_CMD/  for the raw device command interface?

The current implementation needs to be changed anyway :)  From "ATA raw 
command" to "device raw command" at the very least.

    Jeff




^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:22                     ` Jeff Garzik
  2002-03-12  2:33                       ` Linus Torvalds
@ 2002-03-12  2:50                       ` J. Dow
  2002-03-12  3:10                         ` Jeff Garzik
  1 sibling, 1 reply; 107+ messages in thread
From: J. Dow @ 2002-03-12  2:50 UTC (permalink / raw)
  To: Jeff Garzik, Linus Torvalds; +Cc: Bill Davidsen, LKML

From: "Jeff Garzik" <jgarzik@mandrakesoft.com>

> Linus Torvalds wrote:
> 
> >
> >On Mon, 11 Mar 2002, Jeff Garzik wrote:

...

> First, for verification of the driver, it's darned useful to be able to 
> issue ATA commands from userspace.  But since we're being generic, let's 
> just call them device commands, and imagine SCSI perhaps playing in this 
> playground too.

No fooling! (By way of history I was one of the SCSI device driver mavens
for the Amiga. We covered this generic command ground, recovered this ground,
and generally ground this ground into the ground.)

> Second, if you are issuing device commands from userspace, you need to 
> deal with synchronization with the commands being issued from kernel space.

Generally speaking, yes.

> Third, if you have synchronization, that's a good and easy point to add 
> -optional- filtering.

And while I see your point I still ask, "But why?" To make this work the
way it should work you will need a special table of normally disallowed
commands that are allowed for each specific device on the IDE buses
within a machine. You also need this to be generic enough to allow some
commands to go through except for some specific sets of parameters. Now,
I realize that SCSI is more generic than IDE. However, contemplating this
sort of filtering within SCSI device drivers fell into such a point of
silliness that it became the general concensus within the community that
the filtering is inappropriate. In point of fact this proved useful when
technology marched on. The facility within SCSI device drivers for directly
issueing low level commands became instantly important with the advent of
drives that were larger than 2^24 bytes. The normal read/write interface
on the device drivers was byte offset and byte count oriented, even though
it required the byte offsets to be on block boundaries. The direct SCSI
command interface allowed for workaround patches that broke the disk into
several virtual disks. These patches would open the low level driver and
insert themselves as the "real" device driver for the set of devices on
each SCSI bus. This died away fairly quickly as filesystem adaptations
became more popular. These adaptations, in the case finally adopted within
the latest OS revisions, involved an institutionalized driver patch that
presented a proper 64 bit read/write interface to the filesystems. The
fact that the device drivers that are no longer under any sort of
development are patched using direct SCSI commands is neatly hidden
from the users. But it is there and allowed the OS to survive where there
was no further maintenance effort taking place.

I note there seem to be more than one device driver for Linux that is no
longer maintained or poorly maintained. While I doubt this will be the
case for generic IDE, I do suspect that specific IDE interfaces that have
"peculiarities" will fall by the wayside as fewer people use them. It
might be nice to have the ability to patch around these drivers rather
than try to patch then with no test cases handy. It saved a significant
amount of grief on the Amiga. There's no reason I can see that it would
not save grief on Linux.

> Now... the overall point I am trying to sell is...  IFF certain 
> lesser-used device commands are primarily issued from userspace, and IFF 
> it is not reasonable to create a new kernel interface, is it not 
> reasonable to be able to issue raw device commands from userspace?  Just 
> the verification case alone seems like a strong argument.
> 
> Call it device_command not ata_command if you want, and add SCSI 
> support.  Passing in raw device_commands from userspace is useful, IMO. 
>  Throw in filtering of those commands, and life is golden for everybody 
> AFAICS.  There is no need to be ATA specific with these goals...

It might be a good exercise, Jeff, to define the filters in such a way
that potentially harmful commands can be adequately filters while other
potentially "saving" commands can be allowed even if they differ only in
parameters. It is also interesting to note that direct userland ATA and
ATAPI reads and writes are fully as dangerous as any exotic level commands.
Linux seems to allow this danger. What makes the other commands so dangerous?
I'm not as familiar with the Linux SCSI interfaces as with those of the
Amiga. (I've sort of moved on to video work.) However, I wonder if the Linux
SCSI world filters "mode select" and manufacturer defined commands or not.
I suspect they have a longer history with this sort of interface and its
abuse than IDE. It might pay to investigate and adopt consonant postures.

{^_^}   Joanne Dow, jdow@earthlink.net, did Amiga SCSI device drivers for
        a decade or so as a consultant.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:19                         ` Linus Torvalds
  2002-03-12  2:34                           ` Jeff Garzik
@ 2002-03-12  2:54                           ` J. Dow
  2002-03-12  6:32                           ` Vojtech Pavlik
  2 siblings, 0 replies; 107+ messages in thread
From: J. Dow @ 2002-03-12  2:54 UTC (permalink / raw)
  To: Linus Torvalds, Jeff Garzik; +Cc: andersen, Bill Davidsen, LKML

From: "Linus Torvalds" <torvalds@transmeta.com>

> Yeah yeah. You can add additional levels of protection, and we have
> capabilities.
> 
> Add a special password-protected capability, so that only YOU can enable
> certain hardware access stuff. Where does it end? Is one such capability
> enough? How do you initialize the default values for the system if you
> need to be there to type in the password at bootup every time? We're
> talking about some rather fundamental things here, and these are issues
> that go _far_ beyond some silly ATA stack layer.

Linus, this discussion hung on long enough I decided to start reading it.
So I may have missed something. However, I notice you speak of a networking
example. I believe it is a strawman. The real comparison is closer to that
between IDE and SCSI. Do the SCSI device drivers filter? What and how do
they filter if they do at all? Aren't they a better model to adopt for
a system consistent interface philosophy?

{^_^}   Joanne Dow, jdow@earthlink.net



^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  1:41                 ` Jeff Garzik
  2002-03-12  1:44                   ` Linus Torvalds
@ 2002-03-12  2:57                   ` Alan Cox
  2002-03-12  2:49                     ` Jeff Garzik
  2002-03-12 11:10                   ` [patch] My AMD IDE driver, v2.7 Martin Dalecki
  2002-03-12 20:21                   ` Gunther Mayer
  3 siblings, 1 reply; 107+ messages in thread
From: Alan Cox @ 2002-03-12  2:57 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Linus Torvalds, Bill Davidsen, LKML

> Are such random vendor-specific commands really that common?

Not very

> Linus, would it be acceptable to you to include an -optional- filter for 
> ATA commands?  There is definitely a segment of users that would like to 
> firewall their devices, and I think (as crazy as it may sound) that 
> notion is a valid one.

Jeff -I like the idea of the filters - but if the ATA command raw stuff
is CAP_SYS_RAWIO then its the same right set as inb/outb. Beyond that
its a job for the NSA and RSBAC stuff ?

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:50                       ` J. Dow
@ 2002-03-12  3:10                         ` Jeff Garzik
  2002-03-12  3:28                           ` Linus Torvalds
  2002-03-12  4:41                           ` Erik Andersen
  0 siblings, 2 replies; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  3:10 UTC (permalink / raw)
  To: J. Dow; +Cc: Linus Torvalds, LKML

J. Dow wrote:

>From: "Jeff Garzik" <jgarzik@mandrakesoft.com>
>
>>Second, if you are issuing device commands from userspace, you need to 
>>deal with synchronization with the commands being issued from kernel space.
>>
>Generally speaking, yes.
>
cool

>>Third, if you have synchronization, that's a good and easy point to add 
>>-optional- filtering.
>>
>And while I see your point I still ask, "But why?" To make this work the
>way it should work you will need a special table of normally disallowed
>commands that are allowed for each specific device on the IDE buses
>within a machine.
>
[...]

>It might be a good exercise, Jeff, to define the filters in such a way
>that potentially harmful commands can be adequately filters while other
>potentially "saving" commands can be allowed even if they differ only in
>parameters. It is also interesting to note that direct userland ATA and
>
I'm afraid I may have been confusing to the casual reader, because the 
current thread of discussion mutated from talking about (among other 
things) implementation details of the existing ATA raw command "filter" 
and the existing interface for issuing raw ATA commands.

You can, certainly, make a filter that addresses the issues you list. 
 The existing filter is mainly a correctness filter -- it ensures that 
only known and standard ATA commands are passed down to the actual 
devices.  It filters out vendor-specific commands as well as potentially 
nefarious future commands like COPYPROTECT or somesuch.

So, to summarize my points on the thread so far (as modified by Linus's 
responses to me):

1) There should be a raw device command interface (not ATA or SCSI specific)
2) There should be kernel interfaces for the standard cases, so that the 
raw device command interface is often not needed
3) There should be capability to optionally install filter the raw 
device command interface.  The filter is built into the kernel at 
compile-time, but can also be disabled at boot time.

    Jeff





^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  3:10                         ` Jeff Garzik
@ 2002-03-12  3:28                           ` Linus Torvalds
  2002-03-12  3:46                             ` Jeff Garzik
                                               ` (2 more replies)
  2002-03-12  4:41                           ` Erik Andersen
  1 sibling, 3 replies; 107+ messages in thread
From: Linus Torvalds @ 2002-03-12  3:28 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: J. Dow, LKML


On Mon, 11 Mar 2002, Jeff Garzik wrote:
> 
> 1) There should be a raw device command interface (not ATA or SCSI specific)

Well, since the raw commands themselves will be bus-specific, you can't
really avoid THAT part.

The thing I want to be generic is the fact that everybody uses the 
"request->cmd[]" array, along with the flags in "request->flags" to 
specify what kind of command it is.

We actually have this infrastructure already, it's just not fully used.

> 2) There should be kernel interfaces for the standard cases, so that the 
> raw device command interface is often not needed

Absolutely.

> 3) There should be capability to optionally install filter the raw 
> device command interface.  The filter is built into the kernel at 
> compile-time, but can also be disabled at boot time.

This is the part I really don't like.

Thinking like a sysadmin, I want to be able to run programs that I would 
not allow my users to run or want to be run accidentally. And I do _not_ 
want to reboot my kernel just because one of my mirrored disks died, I 
hot-replaced it, and I notice that I need to upgrade the firmware on the 
thing to make it play nice with the other disks in the array.

See? A setup that either allows everything or nothing is fundamentally
flawed in this kind of situation - suddenly I as a sysadmin cannot do
something without bringing the machine down. Which makes all the hotplug
interfaces useless - or then I as a sysadmin just have to leave a kernel 
in place that allows the kinds of raw command accesses that I am so scared 
of.

One solution may be to have the whole raw cmd thing as a loadable module, 
and then I can make sure that it's not even available on the system so 
that I have to do some work to find it, and somebody elses program won't 
just know what to do.

But in that case is should be far removed from the IDE driver - it would 
just be a module that inserts a raw request on the request queue, and NOT 
inside some subsystem driver that I obviously want to have available all 
the time.

See?

		Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:37                         ` Jeff Garzik
@ 2002-03-12  3:34                           ` Olivier Galibert
  2002-03-12  4:13                             ` Jeff Garzik
  2002-03-12 11:23                           ` Martin Dalecki
  1 sibling, 1 reply; 107+ messages in thread
From: Olivier Galibert @ 2002-03-12  3:34 UTC (permalink / raw)
  To: LKML

On Mon, Mar 11, 2002 at 09:37:23PM -0500, Jeff Garzik wrote:
> It serves to encourage openness, nobody is forced to use it, and it 
> provides an additional layer of protection for those that choose to use 
> it.  That is the point.

It doesn't provide any meaningful protection, that's the point.

If you're root/have CAP_SYS_RAWIO, you can bit-bang the interface, you
can patch out the filter from the kernel binary, you can do whatever
pleases you.  Don't run evil programs as root in the first place.  And
if you want to have finer-grained capabilities for specific
drive-level actions, create an higher-level interface for them which
will guarantee that only safe commands are used because they will be
generated by the kernel in the first place.

Broken security is actually worse than no security.  With no security
you at least know what to expect.

The exact same discussion happened with Andre, please refer to it.

  OG.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  3:28                           ` Linus Torvalds
@ 2002-03-12  3:46                             ` Jeff Garzik
  2002-03-12  6:10                               ` J. Dow
  2002-03-12  3:58                             ` Linus Torvalds
  2002-03-12  6:05                             ` J. Dow
  2 siblings, 1 reply; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  3:46 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: J. Dow, LKML

Linus Torvalds wrote:

>On Mon, 11 Mar 2002, Jeff Garzik wrote:
>
>>1) There should be a raw device command interface (not ATA or SCSI specific)
>>
>
>Well, since the raw commands themselves will be bus-specific, you can't
>really avoid THAT part.
>
>The thing I want to be generic is the fact that everybody uses the 
>"request->cmd[]" array, along with the flags in "request->flags" to 
>specify what kind of command it is.
>
>We actually have this infrastructure already, it's just not fully used.
>
I omitted "for userspace" :)

I was referring to having a userspace conduit for submitting requests, a 
la the taskfile ioctl now.


>>3) There should be capability to optionally install filter the raw 
>>device command interface.  The filter is built into the kernel at 
>>compile-time, but can also be disabled at boot time.
>>
>
>This is the part I really don't like.
>
>Thinking like a sysadmin, I want to be able to run programs that I would 
>not allow my users to run or want to be run accidentally. And I do _not_ 
>want to reboot my kernel just because one of my mirrored disks died, I 
>hot-replaced it, and I notice that I need to upgrade the firmware on the 
>thing to make it play nice with the other disks in the array.
>
>See? A setup that either allows everything or nothing is fundamentally
>flawed in this kind of situation - suddenly I as a sysadmin cannot do
>something without bringing the machine down. Which makes all the hotplug
>interfaces useless - or then I as a sysadmin just have to leave a kernel 
>in place that allows the kinds of raw command accesses that I am so scared 
>of.
>
>One solution may be to have the whole raw cmd thing as a loadable module, 
>and then I can make sure that it's not even available on the system so 
>that I have to do some work to find it, and somebody elses program won't 
>just know what to do.
>
>But in that case is should be far removed from the IDE driver - it would 
>just be a module that inserts a raw request on the request queue, and NOT 
>inside some subsystem driver that I obviously want to have available all 
>the time.
>
I like this solution, it was the one I was thinking of :)

The entire userspace raw cmd ioctl should be a separate module for 
precisely the issues you outlined.  If they choose, people can compile 
that module into the static kernel image, including filter.  Or they can 
use the module without the filter.  Or they can not use the module at 
all.  Etc.

I do understand the problems stemming from the inflexibility of the 
filter that's being discussed, but I disagree that it's a fundamental 
flaw.  It's an option that some people -shouldn't- choose, for various 
reasons.  But that's an issue for documentation and system integrators.

    Jeff




^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  3:28                           ` Linus Torvalds
  2002-03-12  3:46                             ` Jeff Garzik
@ 2002-03-12  3:58                             ` Linus Torvalds
  2002-03-12  4:26                               ` Jeff Garzik
                                                 ` (3 more replies)
  2002-03-12  6:05                             ` J. Dow
  2 siblings, 4 replies; 107+ messages in thread
From: Linus Torvalds @ 2002-03-12  3:58 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: LKML, Alan Cox


On Mon, 11 Mar 2002, Linus Torvalds wrote:
> 
> One solution may be to have the whole raw cmd thing as a loadable module, 
> and then I can make sure that it's not even available on the system so 
> that I have to do some work to find it, and somebody elses program won't 
> just know what to do.
> 
> But in that case is should be far removed from the IDE driver - it would 
> just be a module that inserts a raw request on the request queue, and NOT 
> inside some subsystem driver that I obviously want to have available all 
> the time.

Let me put this proposal in more specific terms and see who hollers..

First, the actual assumptions:
 - we should use the request queue, simply because that is the only thing 
   that serializes access to all controllers - if we do not have any 
   "sideband", there is no way to create the kind of confusion that we can
   create right now.

 - we want the approach to be generic, even if the details will end up 
   being IDE/SCSI/xxx-specific.

 - I personally believe that we want to be able to do filtering
   independently of the controller driver, ie the filtering is not part of
   the driver infrastructure at all, but at a higher level (ie the same 
   way network filtering has _nothing_ to do with any actual network
   drivers, regardless of what bus those drivers are on)

Thus I would suggest against a filter inside the IDE driver, and instead 
suggest a loadable module that does

 - attach to one or more request queue(s). Notice that you should not have
   _one_ module that handles all request queues, because the filter module
   obviously has to be different for an ATA disk than for a SCSI disk, and
   in fact it might be different for an IBM ATA disk than for a Maxtor ATA
   disk, for example.

 - the module basically acts the way the SCSI generic driver does right 
   now, except it acts on a higher level: instead of generating SCSI
   requests and feeding them directly to the driver with a scsi_do_req(), 
   it would generate the command requests and feed it to the request 
   queue.

   In fact, don't think of it as the ATA thing at all: I'm more thinking 
   along the lines of splitting up "sg.c" into the highlevel command 
   generator (the biggest part) and a very _small_ part in the scsi 
   request loop that understands about the generic command interface.

If we can really do what sg.c does now, while at the _same_ time also have 
a "ide-generic" module that uses the exact same infrastructure, then I 
think I'm happy. Yes, the filtering is bus-specific (because the commands 
are bus-specific), but the general approach is common.

Does anybody find any real downsides to this approach or basically trying 
to abstract sg.c "upwards" a bit?

		Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  3:34                           ` Olivier Galibert
@ 2002-03-12  4:13                             ` Jeff Garzik
  2002-03-14 14:13                               ` Pavel Machek
  0 siblings, 1 reply; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  4:13 UTC (permalink / raw)
  To: Olivier Galibert; +Cc: LKML

Olivier Galibert wrote:

>On Mon, Mar 11, 2002 at 09:37:23PM -0500, Jeff Garzik wrote:
>
>>It serves to encourage openness, nobody is forced to use it, and it 
>>provides an additional layer of protection for those that choose to use 
>>it.  That is the point.
>>
>
>It doesn't provide any meaningful protection, that's the point.
>
>If you're root/have CAP_SYS_RAWIO, you can bit-bang the interface, you
>can patch out the filter from the kernel binary, you can do whatever
>pleases you.  Don't run evil programs as root in the first place.  And
>if you want to have finer-grained capabilities for specific
>drive-level actions, create an higher-level interface for them which
>will guarantee that only safe commands are used because they will be 
>

Under more restricted domains, root cannot bit-bang the interface. 
 s/CAP_SYS_RAWIO/CAP_DEVICE_CMD/ for the raw cmd ioctl interface.  Have 
the OS trap I/O port accesses using SMM mode if you would like, and that 
applies to your particular security situation.

The filter is useful for other reasons like correctness, as well.

    Jeff





^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  3:58                             ` Linus Torvalds
@ 2002-03-12  4:26                               ` Jeff Garzik
  2002-03-12  4:40                                 ` Linus Torvalds
  2002-03-12  6:26                                 ` J. Dow
  2002-03-12  4:31                               ` Linus Torvalds
                                                 ` (2 subsequent siblings)
  3 siblings, 2 replies; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  4:26 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: LKML, Alan Cox

Your proposal sounds 100% ok to me...

For the details of the userspace interface (for both ATA and SCSI), my 
idea was to use standard read(2) and write(2).

Any number of programs can open /dev/ata/hda/control or 
/dev/scsi/sdc/control.  write(2) submits requests, read(2) consumes 
command responses, perhaps buffering a bit so that multiple responses 
are not lost if userspace is slow.

Maybe it's a cheesy way to avoid ioctl(2), maybe not...

    Jeff





^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  3:58                             ` Linus Torvalds
  2002-03-12  4:26                               ` Jeff Garzik
@ 2002-03-12  4:31                               ` Linus Torvalds
  2002-03-12  5:05                                 ` Jeff Garzik
  2002-03-12 11:39                                 ` Martin Dalecki
  2002-03-12  4:49                               ` Erik Andersen
  2002-03-12 11:36                               ` Martin Dalecki
  3 siblings, 2 replies; 107+ messages in thread
From: Linus Torvalds @ 2002-03-12  4:31 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: LKML


On Mon, 11 Mar 2002, Linus Torvalds wrote:
> 
>  - attach to one or more request queue(s). Notice that you should not have
>    _one_ module that handles all request queues, because the filter module
>    obviously has to be different for an ATA disk than for a SCSI disk, and
>    in fact it might be different for an IBM ATA disk than for a Maxtor ATA
>    disk, for example.

Btw, to tie this back to the other IDE thread, namely the suspend/resume 
thing, I think things like that should also just push commands down the 
request list. In particular, instead of waiting until the handler is NULL, 
it should do something like

 - create a "sync" request
 - do the equivalent of

	DECLARE_COMPLETION(wait);
	rq->waiting = &wait;
	q->elevator.elevator_add_req_fn(q, rq, queue_head);
	wait_for_completion(&wait);

which automatically synchronizes with any outstanding requests (simply 
by virtue of the elevator knowing not to re-order/merge special requests, 
so when the sync command in finished, we know all other commands have 
finished too).

Note that this should be the same code as for a shutdown as well - we
should finish with a flush buffers request and wait for it to have
completed.

I'd like a _lot_ of stuff to stop using "do_xxx_command()", and move toa 
higher layer so that more code can be shared between different subsystems 
(all of these "sync" issues are really completely generic, and should 
_not_ be duplicated across drivers or subsystems).

		Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  4:26                               ` Jeff Garzik
@ 2002-03-12  4:40                                 ` Linus Torvalds
  2002-03-12  6:26                                 ` J. Dow
  1 sibling, 0 replies; 107+ messages in thread
From: Linus Torvalds @ 2002-03-12  4:40 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: LKML, Alan Cox


On Mon, 11 Mar 2002, Jeff Garzik wrote:
> 
> For the details of the userspace interface (for both ATA and SCSI), my 
> idea was to use standard read(2) and write(2).

I like it, but you have to realize that most, if not all, of the commands 
really are not a matter of a read or a write, but a "transaction", which 
is a pair of both (and at least in theory you could have transactions that 
are more complex than just a "command + result", ie more than just a 
write("cmd + outdata")+read("status + indata")).

I agree 100% with the notion of using read/write to do this, but I think
you need to make it very explicit that we _are_ talking about
transactions, and that the file descriptor would act as a "transaction
descriptor" when you do this. The file descriptor is the one that matches
up the write that started the transaction with the read that gets the
status of it - thus allowing multiple concurrent transactions in flight.

And the command has to have some structure, ie it needs to not just be the
low-level command, but also have the information about the "format" of the
transaction (so that the generic layer can build up the correct BIO data
structures for the result, before it actually sees the read itself).

			Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  3:10                         ` Jeff Garzik
  2002-03-12  3:28                           ` Linus Torvalds
@ 2002-03-12  4:41                           ` Erik Andersen
  2002-03-12  4:48                             ` Jeff Garzik
                                               ` (2 more replies)
  1 sibling, 3 replies; 107+ messages in thread
From: Erik Andersen @ 2002-03-12  4:41 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: J. Dow, Linus Torvalds, LKML

On Mon Mar 11, 2002 at 10:10:36PM -0500, Jeff Garzik wrote:
> 1) There should be a raw device command interface (not ATA or SCSI specific)

Hmm.  If such a generic low-level raw device layer were to be
implemented (presumably as the foundation for the block layer), I
expect the interface would be somthing like the cdrom layer, and
would abstract out all the normal things that raw mass-storage
devices can do.

But the minute such a layer is in place, people will begin going
straight to the sub-low-level raw device layers so they can use
all the exciting new extended features of their XP370000 quantum
storage array which needs the special frob-electrons command to
make it work...

 -Erik

--
Erik B. Andersen             http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  4:41                           ` Erik Andersen
@ 2002-03-12  4:48                             ` Jeff Garzik
  2002-03-12  6:30                               ` J. Dow
  2002-03-12  6:29                             ` J. Dow
  2002-03-12 16:36                             ` Bill Davidsen
  2 siblings, 1 reply; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  4:48 UTC (permalink / raw)
  To: andersen; +Cc: J. Dow, Linus Torvalds, LKML

Erik Andersen wrote:

>But the minute such a layer is in place, people will begin going
>straight to the sub-low-level raw device layers so they can use
>all the exciting new extended features of their XP370000 quantum
>storage array which needs the special frob-electrons command to
>make it work...
>

SCSI generic has existed for a while now :)

So this is really just catching up.  And WRT the filtering stuff, people 
are free to use the raw cmd without any filtering at all.  Your choice.

If you mean bit-banging, see my reply to Oliver (Olivier?).

Anyway, Linus's current proposal seems both sane and flexible enough. 
 And the basic infrastructure already exists to shove raw commands onto 
the request queue.

    Jeff





^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  3:58                             ` Linus Torvalds
  2002-03-12  4:26                               ` Jeff Garzik
  2002-03-12  4:31                               ` Linus Torvalds
@ 2002-03-12  4:49                               ` Erik Andersen
  2002-03-12  5:08                                 ` Linus Torvalds
  2002-03-12 11:36                               ` Martin Dalecki
  3 siblings, 1 reply; 107+ messages in thread
From: Erik Andersen @ 2002-03-12  4:49 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Jeff Garzik, LKML, Alan Cox

On Mon Mar 11, 2002 at 07:58:32PM -0800, Linus Torvalds wrote:
> If we can really do what sg.c does now, while at the _same_ time also have 
> a "ide-generic" module that uses the exact same infrastructure, then I 
> think I'm happy. Yes, the filtering is bus-specific (because the commands 
> are bus-specific), but the general approach is common.
> 
> Does anybody find any real downsides to this approach or basically trying 
> to abstract sg.c "upwards" a bit?

Essentially, if I understand what you are saying,  you are
looking for a uniform low-level mass-storage layer that does all
the normal low-level drive access stuff.  Presumably, if done
correctly, this would act as a bus-abstracting foundation upon
which the block layer could be built...

 -Erik

--
Erik B. Andersen             http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  4:31                               ` Linus Torvalds
@ 2002-03-12  5:05                                 ` Jeff Garzik
  2002-03-12  5:20                                   ` Linus Torvalds
  2002-03-12 11:39                                 ` Martin Dalecki
  1 sibling, 1 reply; 107+ messages in thread
From: Jeff Garzik @ 2002-03-12  5:05 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: LKML

Linus Torvalds wrote:

>On Mon, 11 Mar 2002, Linus Torvalds wrote:
>
>> - attach to one or more request queue(s). Notice that you should not have
>>   _one_ module that handles all request queues, because the filter module
>>   obviously has to be different for an ATA disk than for a SCSI disk, and
>>   in fact it might be different for an IBM ATA disk than for a Maxtor ATA
>>   disk, for example.
>>
>
>Btw, to tie this back to the other IDE thread, namely the suspend/resume 
>thing, I think things like that should also just push commands down the 
>request list. In particular, instead of waiting until the handler is NULL, 
>it should do something like
>
> - create a "sync" request
> - do the equivalent of
>
>	DECLARE_COMPLETION(wait);
>	rq->waiting = &wait;
>	q->elevator.elevator_add_req_fn(q, rq, queue_head);
>	wait_for_completion(&wait);
>
>which automatically synchronizes with any outstanding requests (simply 
>by virtue of the elevator knowing not to re-order/merge special requests, 
>so when the sync command in finished, we know all other commands have 
>finished too).
>

Dumb question, why create a separate request?

Why not just have some way to wait for request X (and flag it for 
no-merge/barrier treatment, etc.)?  bios have end_io callbacks...

    Jeff






^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  4:49                               ` Erik Andersen
@ 2002-03-12  5:08                                 ` Linus Torvalds
  0 siblings, 0 replies; 107+ messages in thread
From: Linus Torvalds @ 2002-03-12  5:08 UTC (permalink / raw)
  To: Erik Andersen; +Cc: Jeff Garzik, LKML, Alan Cox



On Mon, 11 Mar 2002, Erik Andersen wrote:
>
> Essentially, if I understand what you are saying,  you are
> looking for a uniform low-level mass-storage layer that does all
> the normal low-level drive access stuff.

Well, yes and no.

It's not really low-level - it's at the same level as the current
"ll_rw_block()" in that it doesn't per se know any real details of any
drivers - it is nothing but a "build this request" layer (with a way of
getting the data back, of course).

So from a driver perspective (or even driver subsystem like IDE or SCSI)
it's actually a high-level request generator.

Now, let me say outright that I have a very specific reason why I'd like
this thing to be done at this level - which really has nothing to do with
Jeff's wishes to create a IDE command parser.

The reason I want to see stuff done _above_ the level of the request queue
is that I really count on the "struct request" as being the abstraction
layer that the current block driver interfaces so sadly lack.

Right now, block drivers are not very well abstracted at all: and this is
a large part of the reason for why we even _have_ things like the SCSI
midlevel layer or the IDE layer in the first place. But both the SCSI
layer and the IDE layer are just fairly messy - with no good way to share
code (no common interfaces) and with very inflexible setups (just look at
how hard it is to do a high-performance SCSI driver, because if you do a
SCSI driver at all you have to do all the interface crap that comes with
the job).

I'm really hoping that some day, if the _only_ interface to the block
driver is "struct request", you can write truly interchangable block
drivers - the same way you can write truly independent network drivers
today. None of this "IDE vs SCSI midlevel layer" crap.

Yes, "struct request" is slightly more complex than just being handed a
packet to send out, but I think that is unavoidable - block devices just
_are_ more complex than sending out a packet on a network. So while it's
not a really simple interface, at least it is a clear border between
drivers. And a SCSI driver would be nothing more than a driver that
accepts at least a subset of the kinds of requests that some scsi module
can push to it.

None of this complex function call interface with common complex
structures that are imposed by hundreds of different drivers that each
have slightly different issues. Just a queue.

"Everything is a stream of bytes" - except in this case the stream just
happens to have enough structure that you can re-order the packets and try
to sort them while they haven't been committed yet.

		Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  5:05                                 ` Jeff Garzik
@ 2002-03-12  5:20                                   ` Linus Torvalds
  0 siblings, 0 replies; 107+ messages in thread
From: Linus Torvalds @ 2002-03-12  5:20 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: LKML



On Tue, 12 Mar 2002, Jeff Garzik wrote:
>
> Dumb question, why create a separate request?

Because you need to anyway. Things like shutdown/suspend need to sync the
caches, and that's a command that needs to go down the pipe to the disk.

> Why not just have some way to wait for request X (and flag it for
> no-merge/barrier treatment, etc.)?  bios have end_io callbacks...

The bio's are just fragment descriptors, they don't really stand on their
own. A bio needs a request in order to move down to the driver.

The request is the place where you find the actual command - the bio just
contains the fragment data of the command.

Of course, the "just" is a big simplification. Since a block command can
be a chain of hundreds of blocks which each actually have a lifetime of
their own, unlike the network later, the fragments are a lot more
complicated than a "skb_frag_t".

So bio's are complex entities in themselves, and they have a life of their
own. It's just that you cannot send a raw bio to a device - the device
wouldn't know what to do with it.

		Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  3:28                           ` Linus Torvalds
  2002-03-12  3:46                             ` Jeff Garzik
  2002-03-12  3:58                             ` Linus Torvalds
@ 2002-03-12  6:05                             ` J. Dow
  2 siblings, 0 replies; 107+ messages in thread
From: J. Dow @ 2002-03-12  6:05 UTC (permalink / raw)
  To: Linus Torvalds, Jeff Garzik; +Cc: LKML

From: "Linus Torvalds" <torvalds@transmeta.com>

> > 3) There should be capability to optionally install filter the raw 
> > device command interface.  The filter is built into the kernel at 
> > compile-time, but can also be disabled at boot time.
> 
> This is the part I really don't like.
> 
> Thinking like a sysadmin, I want to be able to run programs that I would 
> not allow my users to run or want to be run accidentally. And I do _not_ 
> want to reboot my kernel just because one of my mirrored disks died, I 
> hot-replaced it, and I notice that I need to upgrade the firmware on the 
> thing to make it play nice with the other disks in the array.
> 
> See? A setup that either allows everything or nothing is fundamentally
> flawed in this kind of situation - suddenly I as a sysadmin cannot do
> something without bringing the machine down. Which makes all the hotplug
> interfaces useless - or then I as a sysadmin just have to leave a kernel 
> in place that allows the kinds of raw command accesses that I am so scared 
> of.

Good example. (I even implemented something of that sort for downloading
new firmware for Maxtor SCSI drives back when the 1G Panther was a brandy
spanky new thing. I never distributed it and have no plans of doing so.
Amigans as a rule are not good candidates for having such code on hand. The
average Linux SysAdmin should be a few dB smarter and more careful. I don't
think it would be a good thing to force multiple reboots in the situation
you cite. And it does happen.)

{^_^}    Joanne Dow


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  3:46                             ` Jeff Garzik
@ 2002-03-12  6:10                               ` J. Dow
  0 siblings, 0 replies; 107+ messages in thread
From: J. Dow @ 2002-03-12  6:10 UTC (permalink / raw)
  To: Jeff Garzik, Linus Torvalds; +Cc: LKML

From: "Jeff Garzik" <jgarzik@mandrakesoft.com>

> Linus Torvalds wrote:
...
> >One solution may be to have the whole raw cmd thing as a loadable module, 
> >and then I can make sure that it's not even available on the system so 
> >that I have to do some work to find it, and somebody elses program won't 
> >just know what to do.
> >
> >But in that case is should be far removed from the IDE driver - it would 
> >just be a module that inserts a raw request on the request queue, and NOT 
> >inside some subsystem driver that I obviously want to have available all 
> >the time.
> >
> I like this solution, it was the one I was thinking of :)

It leaves me bemused. You speak of a module to install a raw userspace
IO capability. If that module exists the module interface exists. Would
it have to be the module compiled into the kernel that gets run on that
interface? It looks as wide open as ever, to me.

> The entire userspace raw cmd ioctl should be a separate module for 
> precisely the issues you outlined.  If they choose, people can compile 
> that module into the static kernel image, including filter.  Or they can 
> use the module without the filter.  Or they can not use the module at 
> all.  Etc.

Of course, this seems to be one of those compromises between high
availability and high security. It should be made clear that this is
the compromise involved when the raw io filter is compiled in or not.

I'm not sure you can build an unfiltered raw IO capability into the
kernel SCSI, IDE, or anything else and maintain system security.

{^_^}    Joanne


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  1:33                   ` Jeff Garzik
  2002-03-12  1:41                     ` Linus Torvalds
@ 2002-03-12  6:25                     ` Vojtech Pavlik
  1 sibling, 0 replies; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-12  6:25 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: andersen, Bill Davidsen, Linus Torvalds, LKML

On Mon, Mar 11, 2002 at 08:33:42PM -0500, Jeff Garzik wrote:
> Erik Andersen wrote:
> 
> >On Mon Mar 11, 2002 at 07:34:26PM -0500, Jeff Garzik wrote:
> >
> >>Reason 1: Standard kernel convention.  In other ioctls, we check basic 
> >>arguments and return EINVAL when they are wrong, even for privieleged 
> >>ioctls.
> >>
> >
> >I have no argument with basic command validation.  But take a
> >look at ide_cmd_type_parser(), for example.  Do we really need a
> >giant switch statement listing all the allowed commands, just so
> >we can throw back a IDE_DRIVE_TASK_INVALID to user-space if they
> >decide to send down some undocumeted firmware wiping commands?
> >Especially since that giant struct of allowed commands is
> >duplicated in ide_pre_handler_parser() and ide_handler_parser()
> >
> I agree the implementation could be improved.
> 
> Your first question is really philosophical.  I think that people should 
> -not- be able to send undocumented commands through the interface... 
>  and in this area IMO it pays to be paranoid.

Why? What if I really want to update the firmware is say my CD-RW, and
it doesn't use any of the ATA-spec commands for that? Should it fail?

I think filtering bad requests is OK - validating stuff like
permissions, concurrent access, pointers, whatever, but the kernel
shouldn't have hardcoded tables of commands that are allowed.

The "right solution", if we really need command filtering is an ioctl
and an utility that can fill a 'filter table', which says which commands
are ok for whom and which are not. Like 'INQUIRY can be used by anyone',
'no, I won't send anything related to CPRM to the drive'. Easy to
implement, no huge case statements needed.

> If we wanted to be ultra-super-paranoid, drop the ioctl and taskfile 
> parser, and implement the taskfile checks via SMM mode callbacks from 
> activity on the IDE ports ;-)  That way we know the NSA is not doing 
> something sneaky, as well as supporting unlimited SMP bit-banging from 
> userland.  Can you say ug and non-portable even to a lot of ia32 
> platforms.  :)
> 
> So, the implementation may need improvement, but we do (a) want the 
> taskfile ioctl [and one for scsi too], and (b) want to implement some 
> amount of mininal sanity checks on the requests.

-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  4:26                               ` Jeff Garzik
  2002-03-12  4:40                                 ` Linus Torvalds
@ 2002-03-12  6:26                                 ` J. Dow
  2002-03-12 11:44                                   ` Martin Dalecki
  1 sibling, 1 reply; 107+ messages in thread
From: J. Dow @ 2002-03-12  6:26 UTC (permalink / raw)
  To: Jeff Garzik, Linus Torvalds; +Cc: LKML, Alan Cox

From: "Jeff Garzik" <jgarzik@mandrakesoft.com>

> Your proposal sounds 100% ok to me...
> 
> For the details of the userspace interface (for both ATA and SCSI), my 
> idea was to use standard read(2) and write(2).
> 
> Any number of programs can open /dev/ata/hda/control or 
> /dev/scsi/sdc/control.  write(2) submits requests, read(2) consumes 
> command responses, perhaps buffering a bit so that multiple responses 
> are not lost if userspace is slow.
> 
> Maybe it's a cheesy way to avoid ioctl(2), maybe not...

Jeff, from a security aspect would it perhaps be better to have the
filter always in place and load rule sets through a rigidly controlled
interface? This gives a control hook for non-Unixoid security model
control over the interface filtering. The filter module would have the
lower level interfaces all opened exclusively so there would be no
paths around the filter. I propose that the rule sets, for each
device's instance of the filter interface, could be changed to include
anything from a null set to forbidding anything past fully controlled
read and write with no raw IO. One specific entity could be allowed
to make the changes and no others. This gives a single interface for
verifying signatures on filter data sets, as well.

{^_^}



^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  4:41                           ` Erik Andersen
  2002-03-12  4:48                             ` Jeff Garzik
@ 2002-03-12  6:29                             ` J. Dow
  2002-03-12 16:36                             ` Bill Davidsen
  2 siblings, 0 replies; 107+ messages in thread
From: J. Dow @ 2002-03-12  6:29 UTC (permalink / raw)
  To: andersen, Jeff Garzik; +Cc: Linus Torvalds, LKML

From: "Erik Andersen" <andersen@codepoet.org>

> On Mon Mar 11, 2002 at 10:10:36PM -0500, Jeff Garzik wrote:
> > 1) There should be a raw device command interface (not ATA or SCSI specific)
>
> Hmm.  If such a generic low-level raw device layer were to be
> implemented (presumably as the foundation for the block layer), I
> expect the interface would be somthing like the cdrom layer, and
> would abstract out all the normal things that raw mass-storage
> devices can do.
>
> But the minute such a layer is in place, people will begin going
> straight to the sub-low-level raw device layers so they can use
> all the exciting new extended features of their XP370000 quantum
> storage array which needs the special frob-electrons command to
> make it work...

Erik, that is precisely the point on which the Amiga discussions of
the Direct SCSI command capability in scsi device drivers fell down.
(Due to historical oddities even IDE device drivers feature the direct
SCSI interface via emulation. It seems like an ultimate horror. However
it has enabled some marvelously generic tools.)

{^_^}



^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  4:48                             ` Jeff Garzik
@ 2002-03-12  6:30                               ` J. Dow
  0 siblings, 0 replies; 107+ messages in thread
From: J. Dow @ 2002-03-12  6:30 UTC (permalink / raw)
  To: Jeff Garzik, andersen; +Cc: Linus Torvalds, LKML

From: "Jeff Garzik" <jgarzik@mandrakesoft.com>

> SCSI generic has existed for a while now :)

Now we get to the point. What is the SCSI experience with the
generic interface and filtering, if any?

{^_^}


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:19                         ` Linus Torvalds
  2002-03-12  2:34                           ` Jeff Garzik
  2002-03-12  2:54                           ` J. Dow
@ 2002-03-12  6:32                           ` Vojtech Pavlik
  2002-03-14 15:12                             ` Pavel Machek
  2 siblings, 1 reply; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-12  6:32 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Jeff Garzik, andersen, Bill Davidsen, LKML

On Mon, Mar 11, 2002 at 06:19:05PM -0800, Linus Torvalds wrote:

> On Mon, 11 Mar 2002, Jeff Garzik wrote:
> >
> > You have convinced me that unconditional filtering is bad.  But I still
> > think people should be provided the option to filter if they so desire.
> 
> Hey, choice is always good, except if it adds complexity.
> 
> The problem with conditional filtering is that either it is a boot (or
> compile time) option, or it is a dynamic filter.
> 
> If its a dynamic filter, and you don't trust root, what _are_ you going to
> trust? The root program you don't trust might as well be turning the
> filtering off because it wants to be "convenient". And since the only
> programs you really want to filter are _exactly_ the kinds of programs
> that want to avoid filtering, you're just hosed.
> 
> That's my real beef with this whole idiotic parsing thing. Either it is
> fixed (bad, if you don't know what the commands are for all disks) or it
> is trivially overcome in the name of "convenience" (equally bad, since it
> makes the whole thing pointless).

Well, there are uses for the 'dynamic' filter, and it doesn't add too
much complexity. One could be allowing certain commands to be performed
on certain devices by normal users - eg. CD-burning or whatever without
root privileges (I know we're using ide-scsi for the command access
right now ...), and also protecting the oneself from ACPI and the like.
Because ACPI can do IDE commands and does that in a way interfaceable to
a 'taskfile' kernel ioctl. It'd be nice to know a broken ACPI
implementation can't screw up your drive easily through a kernel driver.

-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  0:58                 ` Erik Andersen
  2002-03-12  1:33                   ` Jeff Garzik
@ 2002-03-12  7:13                   ` Erik Andersen
  1 sibling, 0 replies; 107+ messages in thread
From: Erik Andersen @ 2002-03-12  7:13 UTC (permalink / raw)
  To: Jeff Garzik, Bill Davidsen, Linus Torvalds, LKML

On Mon Mar 11, 2002 at 05:58:41PM -0700, Erik wrote:
> I have no argument with basic command validation.  But take a
> look at ide_cmd_type_parser(), for example.  Do we really need a
> giant switch statement listing all the allowed commands, just so
> we can throw back a IDE_DRIVE_TASK_INVALID to user-space if they

In looking closer at the ide driver, it turns out that
ide_cmd_type_parser() is _not_ filtering HDIO_DRIVE_TASKFILE
ioctl commands at all.  My mistake.  There is actually no
filtering at all HDIO_DRIVE_TASKFILE ioctl. 

Strangely enough, ide_cmd_type_parser() is filtering commands
issued by the ide driver itself.

 -Erik

--
Erik B. Andersen             http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-11 22:45         ` Vojtech Pavlik
  2002-03-11 22:53           ` Linus Torvalds
@ 2002-03-12 11:00           ` Martin Dalecki
  2002-03-12 15:59             ` Vojtech Pavlik
                               ` (2 more replies)
  1 sibling, 3 replies; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 11:00 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML

Hello Vojtech.

I have noticed that the ide-timings.h and ide_modules.h are running
much in aprallel in the purpose they serve. Are the any
chances you could dare to care about propagating the
fairly nice ide-timings.h stuff in favour of
ide_modules.h more.

BTW.> I think some stuff from ide-timings.h just belongs
as generic functions intro ide.c, and right now there is
nobody who you need to work from behind ;-).

So please feel free to do the changes you apparently desired
to do a long time ago...


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  1:41                 ` Jeff Garzik
  2002-03-12  1:44                   ` Linus Torvalds
  2002-03-12  2:57                   ` Alan Cox
@ 2002-03-12 11:10                   ` Martin Dalecki
  2002-03-12  0:33                     ` benh
  2002-03-12 20:21                   ` Gunther Mayer
  3 siblings, 1 reply; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 11:10 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Linus Torvalds, Bill Davidsen, LKML

Jeff Garzik wrote:
> Linus Torvalds wrote:
> 
>> The only common factor here is the "synchronize with other requests" - I
>> feel strongly (much more strongly than any parsing notion) that the raw
>> requests have to be passed down the "struct request" and NOT be done the
>> way they are traditionally done (ie completely outside the request 
>> stream,
>> with no synchronization at all with any IO currently in progress).
>>
> agreed
> 
>>> I think "future new commands" is total FUD, the idea that some new 
>>> command
>>> would come along and be so instantly popular, useful and incompatible 
>>> that
>>> all Linux boxes would require it before the next kernel or driver update
>>> is silly at best, and I'm working hard to keep this on a civil plane.
>>>
>>
>> It has nothing to do with "new" commands, and everything to do with
>> "random vendor-specific commands and the vendor-specific tools". Commands
>> that simply should _never_ be parsed in the kernel, because we do not 
>> want
>> to care about 10 different vendors 10 different revisions of their
>> firmware having 10 different small random special commands for that
>> particular drive.
>>
>> In particular, a user that upgrades his hardware should never _ever_ have
>> to upgrade his kernel just because some random disk diagnostic tool needs
>> support for a disk that is new and has new diagnostics.
>>
> Are such random vendor-specific commands really that common?
> 
> Linus, would it be acceptable to you to include an -optional- filter for 
> ATA commands?  There is definitely a segment of users that would like to 
> firewall their devices, and I think (as crazy as it may sound) that 
> notion is a valid one.

If you are *trully paranoid* and want to *fire wall* your device then
the proper way of doing this is to DISABLE those ioctl entierly.
It simple like that. They are not required for regular operation by
concept. Other then this I see no argument here.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:49                     ` Jeff Garzik
@ 2002-03-12 11:17                       ` Alan Cox
  2002-03-13  8:14                       ` ide filters / 'ide dump' / 'bio dump' bert hubert
  1 sibling, 0 replies; 107+ messages in thread
From: Alan Cox @ 2002-03-12 11:17 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Alan Cox, Linus Torvalds, Bill Davidsen, LKML

> Yeah, you can still bit-bang with the current implementation, on that 
> capability.  Couldn't that be cured with s/CAP_SYS_RAWIO/some new 
> CAP_DEVICE_CMD/  for the raw device command interface?

By uploading new firmware you can make the drive return compromised pages
from swap which make an existing RAWIO application do what you want

- so CAP_DEVICE_CMD in the IDE case at least is CAP_SYS_RAWIO

> The current implementation needs to be changed anyway :)  From "ATA raw 
> command" to "device raw command" at the very least.

That assumes a totally generic interface is good - ATA is rather different
to ATAPI/SCSI so it may be best the device interface reflects that.

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:34                           ` Jeff Garzik
@ 2002-03-12 11:21                             ` Martin Dalecki
  0 siblings, 0 replies; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 11:21 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Linus Torvalds, andersen, Bill Davidsen, LKML

Jeff Garzik wrote:
> Linus Torvalds wrote:
> 
>>
>> On Mon, 11 Mar 2002, Jeff Garzik wrote:
>>
>>> You have convinced me that unconditional filtering is bad.  But I still
>>> think people should be provided the option to filter if they so desire.
>>>
>>
>> Hey, choice is always good, except if it adds complexity.
>>
>> The problem with conditional filtering is that either it is a boot (or
>> compile time) option, or it is a dynamic filter.
>>
> heh, I couldn't have given a better argument against a dynamic filter.
> 
> I was actually assuming the filter would be a compile-time option, for 
> security's sake.  Boot-time option works too.
> 
> So, it sounds like you could be sold on an fixed-at-compile-time filter 
> that can be disabled at boot :)  I know you don't like 
> fixed-at-compile-time as you mentioned, but it's my argument there is a 
> class of users that definitely do.  MandrakeSoft would likely enable the 
> filter in the "secure" kernel and disable it in the "normal" kernel, for 
> example.

Mandrake Soft should disable the whole sidestepping
ioctl - even the generic one - in a secure kernel.
Filtering them all to -EINVAL is the bast one can do for *security*.
The stuff which is not should be implemented with generic ioctl
with a proper sementics.

Rings a bell?

No matter how you turn it it turns out that the taskfile stuff as it
is is just useless - formal verification inside the kernel can
be done at coding time. Formal verification for vendor specific
stuff can be done in user land. Formal verification for security
stuff doens't make sense, becouse the whole interface doesn't
make sense for security concerns. Formal verification of the
commands for political reasons is just plain naive...


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  2:37                         ` Jeff Garzik
  2002-03-12  3:34                           ` Olivier Galibert
@ 2002-03-12 11:23                           ` Martin Dalecki
  1 sibling, 0 replies; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 11:23 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Linus Torvalds, Bill Davidsen, LKML

Jeff Garzik wrote:

> It serves to encourage openness, nobody is forced to use it, and it 
> provides an additional layer of protection for those that choose to use 
> it.  That is the point.  It's a choice, and you don't have to enable it 
> in your kernel.  But there seems to be enough demand that it should be 
> at least an option.

No there is no real demand out there. There are just people
arguing over it again and agian on the abstract, without proper
actual usage examples. and most of the time without
proper understanding what setuid == 0 is about.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  3:58                             ` Linus Torvalds
                                                 ` (2 preceding siblings ...)
  2002-03-12  4:49                               ` Erik Andersen
@ 2002-03-12 11:36                               ` Martin Dalecki
  3 siblings, 0 replies; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 11:36 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Jeff Garzik, LKML, Alan Cox

Linus Torvalds wrote:
> On Mon, 11 Mar 2002, Linus Torvalds wrote:
> 
>>One solution may be to have the whole raw cmd thing as a loadable module, 
>>and then I can make sure that it's not even available on the system so 
>>that I have to do some work to find it, and somebody elses program won't 
>>just know what to do.
>>
>>But in that case is should be far removed from the IDE driver - it would 
>>just be a module that inserts a raw request on the request queue, and NOT 
>>inside some subsystem driver that I obviously want to have available all 
>>the time.
>>
> 
> Let me put this proposal in more specific terms and see who hollers..
> 
> First, the actual assumptions:
>  - we should use the request queue, simply because that is the only thing 
>    that serializes access to all controllers - if we do not have any 
>    "sideband", there is no way to create the kind of confusion that we can
>    create right now.

Amen to this.

>  - we want the approach to be generic, even if the details will end up 
>    being IDE/SCSI/xxx-specific.

Could be done but seems to be very optimistic about the actual
detail. However stuff like flush/power up/power down/operate silent/operate fast
should be indeed generic.

>  - I personally believe that we want to be able to do filtering
>    independently of the controller driver, ie the filtering is not part of
>    the driver infrastructure at all, but at a higher level (ie the same 
>    way network filtering has _nothing_ to do with any actual network
>    drivers, regardless of what bus those drivers are on)
> 
> Thus I would suggest against a filter inside the IDE driver, and instead 
> suggest a loadable module that does
> 
>  - attach to one or more request queue(s). Notice that you should not have
>    _one_ module that handles all request queues, because the filter module
>    obviously has to be different for an ATA disk than for a SCSI disk, and
>    in fact it might be different for an IBM ATA disk than for a Maxtor ATA
>    disk, for example.
> 
>  - the module basically acts the way the SCSI generic driver does right 
>    now, except it acts on a higher level: instead of generating SCSI
>    requests and feeding them directly to the driver with a scsi_do_req(), 
>    it would generate the command requests and feed it to the request 
>    queue.
> 
>    In fact, don't think of it as the ATA thing at all: I'm more thinking 
>    along the lines of splitting up "sg.c" into the highlevel command 
>    generator (the biggest part) and a very _small_ part in the scsi 
>    request loop that understands about the generic command interface.

The last part could make the few above possible. But the layering problems
in ide are currently much preventig the most trivial kind of validation.
See for example problems in asynchornous commands, which turned out recently.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  4:31                               ` Linus Torvalds
  2002-03-12  5:05                                 ` Jeff Garzik
@ 2002-03-12 11:39                                 ` Martin Dalecki
  1 sibling, 0 replies; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 11:39 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Jeff Garzik, LKML

Linus Torvalds wrote:
> On Mon, 11 Mar 2002, Linus Torvalds wrote:
> 
>> - attach to one or more request queue(s). Notice that you should not have
>>   _one_ module that handles all request queues, because the filter module
>>   obviously has to be different for an ATA disk than for a SCSI disk, and
>>   in fact it might be different for an IBM ATA disk than for a Maxtor ATA
>>   disk, for example.
>>
> 
> Btw, to tie this back to the other IDE thread, namely the suspend/resume 
> thing, I think things like that should also just push commands down the 
> request list. In particular, instead of waiting until the handler is NULL, 
> it should do something like
> 
>  - create a "sync" request
>  - do the equivalent of
> 
> 	DECLARE_COMPLETION(wait);
> 	rq->waiting = &wait;
> 	q->elevator.elevator_add_req_fn(q, rq, queue_head);
> 	wait_for_completion(&wait);
> 
> which automatically synchronizes with any outstanding requests (simply 
> by virtue of the elevator knowing not to re-order/merge special requests, 
> so when the sync command in finished, we know all other commands have 
> finished too).
> 
> Note that this should be the same code as for a shutdown as well - we
> should finish with a flush buffers request and wait for it to have
> completed.
> 
> I'd like a _lot_ of stuff to stop using "do_xxx_command()", and move toa 
> higher layer so that more code can be shared between different subsystems 
> (all of these "sync" issues are really completely generic, and should 
> _not_ be duplicated across drivers or subsystems).
> 

"Amen Brother" to this. Getting device id strings and others are in the
same gang.

BTW.> Would you dare to care to splow out a 2.5.7-pre1 just to allow
synchronization without bitkeeper?


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  6:26                                 ` J. Dow
@ 2002-03-12 11:44                                   ` Martin Dalecki
  0 siblings, 0 replies; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 11:44 UTC (permalink / raw)
  To: J. Dow; +Cc: Jeff Garzik, Linus Torvalds, LKML, Alan Cox

J. Dow wrote:
> From: "Jeff Garzik" <jgarzik@mandrakesoft.com>
> 
>>Your proposal sounds 100% ok to me...
>>
>>For the details of the userspace interface (for both ATA and SCSI), my 
>>idea was to use standard read(2) and write(2).
>>
>>Any number of programs can open /dev/ata/hda/control or 
>>/dev/scsi/sdc/control.  write(2) submits requests, read(2) consumes 
>>command responses, perhaps buffering a bit so that multiple responses 
>>are not lost if userspace is slow.
>>
>>Maybe it's a cheesy way to avoid ioctl(2), maybe not...
>>
> 
> Jeff, from a security aspect would it perhaps be better to have the
> filter always in place and load rule sets through a rigidly controlled
> interface? 

You are overdesigning by a broad margin. From a security
point of view (I mean the paranoid one) the whole raw interface whatever
filtered or not should *just not be there*.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 11:00           ` Martin Dalecki
@ 2002-03-12 15:59             ` Vojtech Pavlik
  2002-03-12 16:11               ` Martin Dalecki
  2002-03-12 16:17               ` Martin Dalecki
  2002-03-12 20:00             ` [patch] PIIX driver rewrite Vojtech Pavlik
  2002-03-12 20:35             ` Sebastian Droege
  2 siblings, 2 replies; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-12 15:59 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: LKML

[-- Attachment #1: Type: text/plain, Size: 1300 bytes --]

On Tue, Mar 12, 2002 at 12:00:24PM +0100, Martin Dalecki wrote:

> Hello Vojtech.
> 
> I have noticed that the ide-timings.h and ide_modules.h are running
> much in aprallel in the purpose they serve. Are the any
> chances you could dare to care about propagating the
> fairly nice ide-timings.h stuff in favour of
> ide_modules.h more.
> 
> BTW.> I think some stuff from ide-timings.h just belongs
> as generic functions intro ide.c, and right now there is
> nobody who you need to work from behind ;-).
> 
> So please feel free to do the changes you apparently desired
> to do a long time ago...

Hmm, ok. Try this. It shouldn't change any functionality, yet makes a
small step towards cleaning the chipset specific drivers.

Reading through them as I was doing the changes, I found out that most
of them compute the timings incorrectly. Because of that I also removed
the pio blacklist (which is going to come back in a more powerful form,
merged together with the DMA blacklist), because that one is based on
ancient experiments with the broken CMD640 chip and a driver which
doesn't get the timings correct either. The blacklist is plain invalid.

I plan to focus on the most important drivers first, to fix and clean
them, working with the authors where possible.

-- 
Vojtech Pavlik
SuSE Labs

[-- Attachment #2: ide-timing.diff --]
[-- Type: text/plain, Size: 66821 bytes --]

diff -urN linux-2.5.6/drivers/ide/Makefile linux-2.5.6-timing/drivers/ide/Makefile
--- linux-2.5.6/drivers/ide/Makefile	Wed Feb 20 03:10:55 2002
+++ linux-2.5.6-timing/drivers/ide/Makefile	Tue Mar 12 16:26:03 2002
@@ -76,7 +76,7 @@
 
 ide-obj-$(CONFIG_PROC_FS)		+= ide-proc.o
 
-ide-mod-objs		:= ide-taskfile.o ide.o ide-probe.o ide-geometry.o ide-features.o $(ide-obj-y)
+ide-mod-objs		:= ide-taskfile.o ide.o ide-probe.o ide-geometry.o ide-features.o ide-timing.o $(ide-obj-y)
 
 include $(TOPDIR)/Rules.make
 
diff -urN linux-2.5.6/drivers/ide/aec62xx.c linux-2.5.6-timing/drivers/ide/aec62xx.c
--- linux-2.5.6/drivers/ide/aec62xx.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/aec62xx.c	Tue Mar 12 16:26:03 2002
@@ -24,7 +24,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #define DISPLAY_AEC62XX_TIMINGS
 
@@ -412,16 +412,11 @@
 static void aec62xx_tune_drive (ide_drive_t *drive, byte pio)
 {
 	byte speed;
-	byte new_pio = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
 
-	switch(pio) {
-		case 5:		speed = new_pio; break;
-		case 4:		speed = XFER_PIO_4; break;
-		case 3:		speed = XFER_PIO_3; break;
-		case 2:		speed = XFER_PIO_2; break;
-		case 1:		speed = XFER_PIO_1; break;
-		default:	speed = XFER_PIO_0; break;
-	}
+	if (pio == 255)
+		speed = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
+	else
+		speed = XFER_PIO_0 + min_t(byte, pio, 4);
 
 	switch(HWIF(drive)->pci_dev->device) {
 		case PCI_DEVICE_ID_ARTOP_ATP850UF:
diff -urN linux-2.5.6/drivers/ide/ali14xx.c linux-2.5.6-timing/drivers/ide/ali14xx.c
--- linux-2.5.6/drivers/ide/ali14xx.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/ali14xx.c	Tue Mar 12 16:26:03 2002
@@ -48,7 +48,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 /* port addresses for auto-detection */
 #define ALI_NUM_PORTS 4
@@ -67,8 +67,6 @@
 	{0x35, 0x03}, {0x00, 0x00}
 };
 
-#define ALI_MAX_PIO 4
-
 /* timing parameter registers for each drive */
 static struct { byte reg1, reg2, reg3, reg4; } regTab[4] = {
 	{0x03, 0x26, 0x04, 0x27},     /* drive 0 */
@@ -114,21 +112,26 @@
 	int time1, time2;
 	byte param1, param2, param3, param4;
 	unsigned long flags;
-	ide_pio_data_t d;
+	struct ide_timing *t;
+
+	if (pio == 255)
+		pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
+	else
+		pio = XFER_PIO_0 + min_t(byte, pio, 4);
 
-	pio = ide_get_best_pio_mode(drive, pio, ALI_MAX_PIO, &d);
+	t = ide_timing_find_mode(pio);
 
 	/* calculate timing, according to PIO mode */
-	time1 = d.cycle_time;
-	time2 = ide_pio_timings[pio].active_time;
+	time1 = t->cycle;
+	time2 = t->active;
 	param3 = param1 = (time2 * system_bus_speed + 999) / 1000;
 	param4 = param2 = (time1 * system_bus_speed + 999) / 1000 - param1;
-	if (pio < 3) {
+	if (pio < XFER_PIO_3) {
 		param3 += 8;
 		param4 += 8;
 	}
 	printk("%s: PIO mode%d, t1=%dns, t2=%dns, cycles = %d+%d, %d+%d\n",
-		drive->name, pio, time1, time2, param1, param2, param3, param4);
+		drive->name, pio - XFER_PIO_0, time1, time2, param1, param2, param3, param4);
 
 	/* stuff timing parameters into controller registers */
 	driveNum = (HWIF(drive)->index << 1) + drive->select.b.unit;
diff -urN linux-2.5.6/drivers/ide/alim15x3.c linux-2.5.6-timing/drivers/ide/alim15x3.c
--- linux-2.5.6/drivers/ide/alim15x3.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/alim15x3.c	Tue Mar 12 16:26:03 2002
@@ -26,7 +26,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #define DISPLAY_ALI_TIMINGS
 
@@ -241,7 +241,7 @@
 
 static void ali15x3_tune_drive (ide_drive_t *drive, byte pio)
 {
-	ide_pio_data_t d;
+	struct ide_timing *t;
 	ide_hwif_t *hwif = HWIF(drive);
 	struct pci_dev *dev = hwif->pci_dev;
 	int s_time, a_time, c_time;
@@ -250,15 +250,21 @@
 	int port = hwif->index ? 0x5c : 0x58;
 	int portFIFO = hwif->channel ? 0x55 : 0x54;
 	byte cd_dma_fifo = 0;
+	
+	if (pio == 255)
+		pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
+	else
+		pio = XFER_PIO_0 + min_t(byte, pio, 4);
 
-	pio = ide_get_best_pio_mode(drive, pio, 5, &d);
-	s_time = ide_pio_timings[pio].setup_time;
-	a_time = ide_pio_timings[pio].active_time;
+	t = ide_timing_find_mode(pio);	
+	
+	s_time = t->setup;
+	a_time = t->active;
 	if ((s_clc = (s_time * system_bus_speed + 999) / 1000) >= 8)
 		s_clc = 0;
 	if ((a_clc = (a_time * system_bus_speed + 999) / 1000) >= 8)
 		a_clc = 0;
-	c_time = ide_pio_timings[pio].cycle_time;
+	c_time = t->cycle;
 
 #if 0
 	if ((r_clc = ((c_time - s_time - a_time) * system_bus_speed + 999) / 1000) >= 16)
@@ -295,17 +301,6 @@
 	pci_write_config_byte(dev, port, s_clc);
 	pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc);
 	__restore_flags(flags);
-
-	/*
-	 * setup   active  rec
-	 * { 70,   165,    365 },   PIO Mode 0
-	 * { 50,   125,    208 },   PIO Mode 1
-	 * { 30,   100,    110 },   PIO Mode 2
-	 * { 30,   80,     70  },   PIO Mode 3 with IORDY
-	 * { 25,   70,     25  },   PIO Mode 4 with IORDY  ns
-	 * { 20,   50,     30  }    PIO Mode 5 with IORDY (nonstandard)
-	 */
-
 }
 
 static int ali15x3_tune_chipset (ide_drive_t *drive, byte speed)
diff -urN linux-2.5.6/drivers/ide/amd74xx.c linux-2.5.6-timing/drivers/ide/amd74xx.c
--- linux-2.5.6/drivers/ide/amd74xx.c	Tue Mar 12 16:05:37 2002
+++ linux-2.5.6-timing/drivers/ide/amd74xx.c	Tue Mar 12 16:26:03 2002
@@ -235,7 +235,7 @@
 				drive->dn >> 1, drive->dn & 1);
 
 	T = 1000000000 / amd_clock;
-	UT = T / MIN(MAX(amd_config->flags & AMD_UDMA, 1), 2);
+	UT = T / min_t(int, max_t(int, amd_config->flags & AMD_UDMA, 1), 2);
 
 	ide_timing_compute(drive, speed, &t, T, UT);
 
@@ -270,7 +270,7 @@
 		return;
 	}
 
-	amd_set_drive(drive, XFER_PIO_0 + MIN(pio, 5));
+	amd_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5));
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
diff -urN linux-2.5.6/drivers/ide/cmd640.c linux-2.5.6-timing/drivers/ide/cmd640.c
--- linux-2.5.6/drivers/ide/cmd640.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/cmd640.c	Tue Mar 12 16:29:48 2002
@@ -112,7 +112,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 /*
  * This flag is set in ide.c by the parameter:  ide0=cmd640_vlb
@@ -589,15 +589,11 @@
 /*
  * Set a specific pio_mode for a drive
  */
-static void cmd640_set_mode (unsigned int index, byte pio_mode, unsigned int cycle_time)
+static void cmd640_set_mode (unsigned int index, byte pio_mode, unsigned int cycle_time, unsigned int active_time, unsigned int setup_time)
 {
-	int setup_time, active_time, recovery_time, clock_time;
+	int recovery_time, clock_time;
 	byte setup_count, active_count, recovery_count, recovery_count2, cycle_count;
 
-	if (pio_mode > 5)
-		pio_mode = 5;
-	setup_time  = ide_pio_timings[pio_mode].setup_time;
-	active_time = ide_pio_timings[pio_mode].active_time;
 	recovery_time = cycle_time - (setup_time + active_time);
 	clock_time = 1000 / system_bus_speed;
 	cycle_count = (cycle_time + clock_time - 1) / clock_time;
@@ -646,7 +642,7 @@
 static void cmd640_tune_drive (ide_drive_t *drive, byte mode_wanted)
 {
 	byte b;
-	ide_pio_data_t  d;
+	struct ide_timing *t;
 	unsigned int index = 0;
 
 	while (drive != cmd_drives[index]) {
@@ -674,14 +670,16 @@
 			return;
 	}
 
-	(void) ide_get_best_pio_mode (drive, mode_wanted, 5, &d);
-	cmd640_set_mode (index, d.pio_mode, d.cycle_time);
+	if (mode_wanted == 255)
+		t = ide_timing_find_mode(ide_find_best_mode(drive, XFER_PIO | XFER_EPIO));
+	else
+		t = ide_timing_find_mode(XFER_PIO_0 + min_t(byte, mode_wanted, 4));
+
+	cmd640_set_mode(index, t->mode - XFER_PIO_0, t->cycle, t->active, t->setup);
+
+	printk ("%s: selected cmd640 PIO mode%d (%dns)",
+		drive->name, t->mode, t->cycle);
 
-	printk ("%s: selected cmd640 PIO mode%d (%dns)%s",
-		drive->name,
-		d.pio_mode,
-		d.cycle_time,
-		d.overridden ? " (overriding vendor mode)" : "");
 	display_clocks(index);
 	return;
 }
diff -urN linux-2.5.6/drivers/ide/cmd64x.c linux-2.5.6-timing/drivers/ide/cmd64x.c
--- linux-2.5.6/drivers/ide/cmd64x.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/cmd64x.c	Tue Mar 12 16:26:03 2002
@@ -23,7 +23,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #ifndef SPLIT_BYTE
 #define SPLIT_BYTE(B,H,L)	((H)=(B>>4), (L)=(B-((B>>4)<<4)))
@@ -279,10 +279,10 @@
  */
 static void cmd64x_tuneproc (ide_drive_t *drive, byte mode_wanted)
 {
-	int setup_time, active_time, recovery_time, clock_time, pio_mode, cycle_time;
+	int recovery_time, clock_time;
 	byte recovery_count2, cycle_count;
 	int setup_count, active_count, recovery_count;
-	ide_pio_data_t  d;
+	struct ide_timing *t;
 
 	switch (mode_wanted) {
 		case 8: /* set prefetch off */
@@ -291,27 +291,21 @@
 			/*set_prefetch_mode(index, mode_wanted);*/
 			cmdprintk("%s: %sabled cmd640 prefetch\n", drive->name, mode_wanted ? "en" : "dis");
 			return;
+		case 255: mode_wanted = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
 	}
 
-	mode_wanted = ide_get_best_pio_mode (drive, mode_wanted, 5, &d);
-	pio_mode = d.pio_mode;
-	cycle_time = d.cycle_time;
+	t = ide_timing_find_mode(XFER_PIO_0 + min_t(byte, mode_wanted, 4));
 
 	/*
 	 * I copied all this complicated stuff from cmd640.c and made a few minor changes.
 	 * For now I am just going to pray that it is correct.
 	 */
-	if (pio_mode > 5)
-		pio_mode = 5;
-	setup_time  = ide_pio_timings[pio_mode].setup_time;
-	active_time = ide_pio_timings[pio_mode].active_time;
-	recovery_time = cycle_time - (setup_time + active_time);
-	clock_time = 1000 / system_bus_speed;
-	cycle_count = (cycle_time + clock_time - 1) / clock_time;
-
-	setup_count = (setup_time + clock_time - 1) / clock_time;
 
-	active_count = (active_time + clock_time - 1) / clock_time;
+	recovery_time = t->cycle - (t->setup + t->active);
+	clock_time = 1000 / system_bus_speed;
+	cycle_count = (t->cycle + clock_time - 1) / clock_time;
+	setup_count = (t->setup + clock_time - 1) / clock_time;
+	active_count = (t->active + clock_time - 1) / clock_time;
 
 	recovery_count = (recovery_time + clock_time - 1) / clock_time;
 	recovery_count2 = cycle_count - (setup_count + active_count);
@@ -334,9 +328,8 @@
 	 */
 	program_drive_counts (drive, setup_count, active_count, recovery_count);
 
-	cmdprintk("%s: selected cmd646 PIO mode%d : %d (%dns)%s, clocks=%d/%d/%d\n",
-		drive->name, pio_mode, mode_wanted, cycle_time,
-		d.overridden ? " (overriding vendor mode)" : "",
+	cmdprintk("%s: selected cmd646 PIO mode%d : %d (%dns), clocks=%d/%d/%d\n",
+		drive->name, t.mode - XFER_PIO_0, mode_wanted, cycle_time,
 		setup_count, active_count, recovery_count);
 }
 
@@ -391,7 +384,7 @@
 static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, byte set_speed)
 {
 	byte speed	= 0x00;
-	byte set_pio	= ide_get_best_pio_mode(drive, 4, 5, NULL);
+	byte set_pio	= ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 
 	cmd64x_tuneproc(drive, set_pio);
 	speed = XFER_PIO_0 + set_pio;
@@ -408,7 +401,7 @@
 	u8 speed		= 0x00;
 	u8 mode_pci		= 0x00;
 	u8 channel_timings	= cmd680_taskfile_timing(hwif);
-	u8 set_pio		= ide_get_best_pio_mode(drive, 4, 5, NULL);
+	u8 set_pio		= ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 
 	pci_read_config_byte(dev, addr_mask, &mode_pci);
 	mode_pci &= ~((unit) ? 0x30 : 0x03);
diff -urN linux-2.5.6/drivers/ide/cs5530.c linux-2.5.6-timing/drivers/ide/cs5530.c
--- linux-2.5.6/drivers/ide/cs5530.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/cs5530.c	Tue Mar 12 16:26:03 2002
@@ -27,7 +27,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #define DISPLAY_CS5530_TIMINGS
 
@@ -114,10 +114,13 @@
 {
 	ide_hwif_t	*hwif = HWIF(drive);
 	unsigned int	format, basereg = CS5530_BASEREG(hwif);
-	static byte	modes[5] = {XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4};
 
-	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
-	if (!cs5530_set_xfer_mode(drive, modes[pio])) {
+	if (pio == 255)
+		pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
+	else
+		pio = XFER_PIO_0 + min_t(byte, pio, 4);
+
+	if (!cs5530_set_xfer_mode(drive, pio)) {
 		format = (inl(basereg+4) >> 31) & 1;
 		outl(cs5530_pio_timings[format][pio], basereg+(drive->select.b.unit<<3));
 	}
diff -urN linux-2.5.6/drivers/ide/cy82c693.c linux-2.5.6-timing/drivers/ide/cy82c693.c
--- linux-2.5.6/drivers/ide/cy82c693.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/cy82c693.c	Tue Mar 12 16:26:03 2002
@@ -53,7 +53,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 /* the current version */
 #define CY82_VERSION	"CY82C693U driver v0.34 99-13-12 Andreas S. Krebs (akrebs@altavista.net)"
@@ -140,8 +140,11 @@
  */ 
 static void compute_clocks (byte pio, pio_clocks_t *p_pclk)
 {
+	struct ide_timing *t;
 	int clk1, clk2;
 
+	t = ide_timing_find_mode(XFER_PIO_0 + pio);
+
 	/* we don't check against CY82C693's min and max speed,
 	 * so you can play with the idebus=xx parameter
 	 */
@@ -150,15 +153,13 @@
 		pio = CY82C693_MAX_PIO;
 
 	/* let's calc the address setup time clocks */
-	p_pclk->address_time = (byte)calc_clk(ide_pio_timings[pio].setup_time, system_bus_speed);
+	p_pclk->address_time = (byte)calc_clk(t->setup, system_bus_speed);
 
 	/* let's calc the active and recovery time clocks */
-	clk1 = calc_clk(ide_pio_timings[pio].active_time, system_bus_speed);
+	clk1 = calc_clk(t->active, system_bus_speed);
 
 	/* calc recovery timing */
-	clk2 =	ide_pio_timings[pio].cycle_time -
-		ide_pio_timings[pio].active_time -
-		ide_pio_timings[pio].setup_time;
+	clk2 =	t->cycle - t->active - t->setup;
 
 	clk2 = calc_clk(clk2, system_bus_speed);
 
@@ -166,7 +167,7 @@
 
 	/* note: we use the same values for 16bit IOR and IOW
          *	those are all the same, since I don't have other
-	 *	timings than those from ide_modes.h
+	 *	timings than those from ide-timing.h
 	 */
 
 	p_pclk->time_16r = (byte)clk1;
@@ -321,7 +322,7 @@
 #endif /* CY82C693_DEBUG_LOGS */
 
         /* first let's calc the pio modes */
-	pio = ide_get_best_pio_mode(drive, pio, CY82C693_MAX_PIO, NULL);
+	pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 
 #if CY82C693_DEBUG_INFO
 	printk (KERN_INFO "%s: Selected PIO mode %d\n", drive->name, pio);
diff -urN linux-2.5.6/drivers/ide/dtc2278.c linux-2.5.6-timing/drivers/ide/dtc2278.c
--- linux-2.5.6/drivers/ide/dtc2278.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/dtc2278.c	Tue Mar 12 16:26:03 2002
@@ -15,7 +15,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 /*
  * Changing this #undef to #define may solve start up problems in some systems.
@@ -70,7 +70,7 @@
 {
 	unsigned long flags;
 
-	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+	pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 
 	if (pio >= 3) {
 		save_flags(flags);	/* all CPUs */
diff -urN linux-2.5.6/drivers/ide/hpt34x.c linux-2.5.6-timing/drivers/ide/hpt34x.c
--- linux-2.5.6/drivers/ide/hpt34x.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/hpt34x.c	Tue Mar 12 16:26:03 2002
@@ -40,7 +40,7 @@
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #ifndef SPLIT_BYTE
 #define SPLIT_BYTE(B,H,L)	((H)=(B>>4), (L)=(B-((B>>4)<<4)))
@@ -152,9 +152,9 @@
 
 	byte	timing, speed, pio;
 
-	pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
+	pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 
-	if (xfer_pio> 4)
+	if (xfer_pio > 4)
 		xfer_pio = 0;
 
 	if (drive->id->eide_pio_iordy > 0) {
diff -urN linux-2.5.6/drivers/ide/hpt366.c linux-2.5.6-timing/drivers/ide/hpt366.c
--- linux-2.5.6/drivers/ide/hpt366.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/hpt366.c	Tue Mar 12 16:26:03 2002
@@ -61,7 +61,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #define DISPLAY_HPT366_TIMINGS
 
@@ -600,9 +600,9 @@
 	unsigned short xfer_pio = drive->id->eide_pio_modes;
 	byte	timing, speed, pio;
 
-	pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
+	pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 
-	if (xfer_pio> 4)
+	if (xfer_pio > 4)
 		xfer_pio = 0;
 
 	if (drive->id->eide_pio_iordy > 0) {
diff -urN linux-2.5.6/drivers/ide/ht6560b.c linux-2.5.6-timing/drivers/ide/ht6560b.c
--- linux-2.5.6/drivers/ide/ht6560b.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/ht6560b.c	Tue Mar 12 16:26:03 2002
@@ -44,7 +44,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 /* #define DEBUG */  /* remove comments for DEBUG messages */
 
@@ -199,20 +199,23 @@
 {
 	int active_time, recovery_time;
 	int active_cycles, recovery_cycles;
-	ide_pio_data_t d;
+	struct ide_timing *t;
 	
         if (pio) {
-		pio = ide_get_best_pio_mode(drive, pio, 5, &d);
+		if (pio == 255)
+			pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
+		else
+			pio = XFER_PIO_0 + min_t(byte, pio, 4);
+
+		t = ide_timing_find_mode(pio);
 		
 		/*
 		 *  Just like opti621.c we try to calculate the
 		 *  actual cycle time for recovery and activity
 		 *  according system bus speed.
 		 */
-		active_time = ide_pio_timings[pio].active_time;
-		recovery_time = d.cycle_time 
-			- active_time
-			- ide_pio_timings[pio].setup_time;
+		active_time = t->active;
+		recovery_time = t->cycle - active_time - t->setup;
 		/*
 		 *  Cycle times should be Vesa bus cycles
 		 */
@@ -227,7 +230,8 @@
 		if (recovery_cycles > 15) recovery_cycles = 0;  /* 0==16 */
 		
 #ifdef DEBUG
-		printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n", drive->name, pio, recovery_cycles, recovery_time, active_cycles, active_time);
+		printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n",
+			drive->name, pio - XFER_PIO_0, recovery_cycles, recovery_time, active_cycles, active_time);
 #endif
 		
 		return (byte)((recovery_cycles << 4) | active_cycles);
diff -urN linux-2.5.6/drivers/ide/icside.c linux-2.5.6-timing/drivers/ide/icside.c
--- linux-2.5.6/drivers/ide/icside.c	Wed Feb 20 03:10:55 2002
+++ linux-2.5.6-timing/drivers/ide/icside.c	Tue Mar 12 16:26:03 2002
@@ -351,90 +351,6 @@
 	return ide_error(drive, "dma_intr", stat);
 }
 
-/*
- * The following is a sick duplication from ide-dma.c ;(
- *
- * This should be defined in one place only.
- */
-struct drive_list_entry {
-	char * id_model;
-	char * id_firmware;
-};
-
-static struct drive_list_entry drive_whitelist [] = {
-	{ "Micropolis 2112A",			"ALL"		},
-	{ "CONNER CTMA 4000",			"ALL"		},
-	{ "CONNER CTT8000-A",			"ALL"		},
-	{ "ST34342A",				"ALL"		},
-	{ NULL,					0		}
-};
-
-static struct drive_list_entry drive_blacklist [] = {
-	{ "WDC AC11000H",			"ALL"		},
-	{ "WDC AC22100H",			"ALL"		},
-	{ "WDC AC32500H",			"ALL"		},
-	{ "WDC AC33100H",			"ALL"		},
-	{ "WDC AC31600H",			"ALL"		},
-	{ "WDC AC32100H",			"24.09P07"	},
-	{ "WDC AC23200L",			"21.10N21"	},
-	{ "Compaq CRD-8241B",			"ALL"		},
-	{ "CRD-8400B",				"ALL"		},
-	{ "CRD-8480B",				"ALL"		},
-	{ "CRD-8480C",				"ALL"		},
-	{ "CRD-8482B",				"ALL"		},
- 	{ "CRD-84",				"ALL"		},
-	{ "SanDisk SDP3B",			"ALL"		},
-	{ "SanDisk SDP3B-64",			"ALL"		},
-	{ "SANYO CD-ROM CRD",			"ALL"		},
-	{ "HITACHI CDR-8",			"ALL"		},
-	{ "HITACHI CDR-8335",			"ALL"		},
-	{ "HITACHI CDR-8435",			"ALL"		},
-	{ "Toshiba CD-ROM XM-6202B",		"ALL"		},
-	{ "CD-532E-A",				"ALL"		},
-	{ "E-IDE CD-ROM CR-840",		"ALL"		},
-	{ "CD-ROM Drive/F5A",			"ALL"		},
-	{ "RICOH CD-R/RW MP7083A",		"ALL"		},
-	{ "WPI CDD-820",			"ALL"		},
-	{ "SAMSUNG CD-ROM SC-148C",		"ALL"		},
-	{ "SAMSUNG CD-ROM SC-148F",		"ALL"		},
-	{ "SAMSUNG CD-ROM SC",			"ALL"		},
-	{ "SanDisk SDP3B-64",			"ALL"		},
-	{ "SAMSUNG CD-ROM SN-124",		"ALL"		},
-	{ "PLEXTOR CD-R PX-W8432T",		"ALL"		},
-	{ "ATAPI CD-ROM DRIVE 40X MAXIMUM",	"ALL"		},
-	{ "_NEC DV5800A",			"ALL"		},
-	{ NULL,					0		}
-};
-
-static int in_drive_list(struct hd_driveid *id, struct drive_list_entry * drive_table)
-{
-	for ( ; drive_table->id_model ; drive_table++)
-		if ((!strcmp(drive_table->id_model, id->model)) &&
-		    ((!strstr(drive_table->id_firmware, id->fw_rev)) ||
-		     (!strcmp(drive_table->id_firmware, "ALL"))))
-			return 1;
-	return 0;
-}
-
-/*
- *  For both Blacklisted and Whitelisted drives.
- *  This is setup to be called as an extern for future support
- *  to other special driver code.
- */
-static int icside_check_drive_lists(ide_drive_t *drive, int good_bad)
-{
-	struct hd_driveid *id = drive->id;
-
-	if (good_bad) {
-		return in_drive_list(id, drive_whitelist);
-	} else {
-		int blacklist = in_drive_list(id, drive_blacklist);
-		if (blacklist)
-			printk("%s: Disabling DMA for %s\n", drive->name, id->model);
-		return(blacklist);
-	}
-	return 0;
-}
 
 static int
 icside_dma_check(ide_drive_t *drive)
@@ -449,14 +365,6 @@
 		goto out;
 
 	/*
-	 * Consult the list of known "bad" drives
-	 */
-	if (icside_check_drive_lists(drive, 0)) {
-		func = ide_dma_off;
-		goto out;
-	}
-
-	/*
 	 * Enable DMA on any drive that has multiword DMA
 	 */
 	if (id->field_valid & 2) {
@@ -473,16 +381,6 @@
 		goto out;
 	}
 
-	/*
-	 * Consult the list of known "good" drives
-	 */
-	if (icside_check_drive_lists(drive, 1)) {
-		if (id->eide_dma_time > 150)
-			goto out;
-		xfer_mode = XFER_MW_DMA_1;
-		func = ide_dma_on;
-	}
-
 out:
 	func = icside_config_if(drive, xfer_mode);
 
@@ -562,11 +460,6 @@
 
 	case ide_dma_test_irq:
 		return inb((unsigned long)hwif->hw.priv) & 1;
-
-	case ide_dma_bad_drive:
-	case ide_dma_good_drive:
-		return icside_check_drive_lists(drive, (func ==
-						ide_dma_good_drive));
 
 	case ide_dma_verbose:
 		return icside_dma_verbose(drive);
diff -urN linux-2.5.6/drivers/ide/ide-m8xx.c linux-2.5.6-timing/drivers/ide/ide-m8xx.c
--- linux-2.5.6/drivers/ide/ide-m8xx.c	Wed Feb 20 03:11:02 2002
+++ linux-2.5.6-timing/drivers/ide/ide-m8xx.c	Tue Mar 12 16:26:03 2002
@@ -37,7 +37,7 @@
 #include <asm/machdep.h>
 #include <asm/irq.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 static int identify  (volatile unsigned char *p);
 static void print_fixed (volatile unsigned char *p);
 static void print_funcid (int func);
@@ -222,19 +222,19 @@
 		/* Compute clock cycles for PIO timings */
 		for (i=0; i<6; ++i) {
 			bd_t	*binfo = (bd_t *)__res;
+			struct ide_timing *t;
+
+			t = ide_timing_find_mode(i + XFER_PIO_0);
 
 			hold_time[i]   =
 				PCMCIA_MK_CLKS (hold_time[i],
 						binfo->bi_busfreq);
 			ide_pio_clocks[i].setup_time  =
-				PCMCIA_MK_CLKS (ide_pio_timings[i].setup_time,
-						binfo->bi_busfreq);
+				PCMCIA_MK_CLKS (t->setup, binfo->bi_busfreq);
 			ide_pio_clocks[i].active_time =
-				PCMCIA_MK_CLKS (ide_pio_timings[i].active_time,
-						binfo->bi_busfreq);
+				PCMCIA_MK_CLKS (t->active, binfo->bi_busfreq);
 			ide_pio_clocks[i].cycle_time  =
-				PCMCIA_MK_CLKS (ide_pio_timings[i].cycle_time,
-						binfo->bi_busfreq);
+				PCMCIA_MK_CLKS (t->cycle, binfo->bi_busfreq);
 #if 0
 			printk ("PIO mode %d timings: %d/%d/%d => %d/%d/%d\n",
 				i,
@@ -242,10 +242,7 @@
 				ide_pio_clocks[i].active_time,
 				ide_pio_clocks[i].hold_time,
 				ide_pio_clocks[i].cycle_time,
-				ide_pio_timings[i].setup_time,
-				ide_pio_timings[i].active_time,
-				ide_pio_timings[i].hold_time,
-				ide_pio_timings[i].cycle_time);
+				t->setup, t->active, hold_time[i], t->cycle);
 #endif
 		}
 	}
@@ -429,13 +426,13 @@
 static void
 m8xx_ide_tuneproc(ide_drive_t *drive, byte pio)
 {
-	ide_pio_data_t d;
 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
 	volatile pcmconf8xx_t	*pcmp;
 	ulong timing, mask, reg;
 #endif
 
-	pio = ide_get_best_pio_mode(drive, pio, 4, &d);
+	if (pio == 255)
+		pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 
 #if 1
 	printk("%s[%d] %s: best PIO mode: %d\n",
diff -urN linux-2.5.6/drivers/ide/ide-pmac.c linux-2.5.6-timing/drivers/ide/ide-pmac.c
--- linux-2.5.6/drivers/ide/ide-pmac.c	Wed Feb 20 03:11:04 2002
+++ linux-2.5.6-timing/drivers/ide/ide-pmac.c	Tue Mar 12 16:26:03 2002
@@ -36,7 +36,7 @@
 #include <linux/pmu.h>
 #include <asm/irq.h>
 #endif
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc);
 
@@ -282,7 +282,7 @@
 static void
 pmac_ide_tuneproc(ide_drive_t *drive, byte pio)
 {
-	ide_pio_data_t d;
+	struct ide_timing *t;
 	int i;
 	u32 *timings;
 	int accessTicks, recTicks;
@@ -290,9 +290,15 @@
 	i = pmac_ide_find(drive);
 	if (i < 0)
 		return;
+	
+	if (pio = 255)	
+		pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
+	else
+		pio = XFER_PIO_0 + min_t(byte, pio, 4);
 		
-	pio = ide_get_best_pio_mode(drive, pio, 4, &d);
-	accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time);
+	t = ide_timing_find_mode(pio);
+	
+	accessTicks = SYSCLK_TICKS(t->active);
 	if (drive->select.all & 0x10)
 		timings = &pmac_ide[i].timings[1];
 	else
@@ -300,16 +306,16 @@
 	
 	if (pmac_ide[i].kind == controller_kl_ata4) {
 		/* The "ata-4" IDE controller of Core99 machines */
-		accessTicks = SYSCLK_TICKS_UDMA(ide_pio_timings[pio].active_time * 1000);
-		recTicks = SYSCLK_TICKS_UDMA(d.cycle_time * 1000) - accessTicks;
+		accessTicks = SYSCLK_TICKS_UDMA(t->active * 1000);
+		recTicks = SYSCLK_TICKS_UDMA(t->cycle * 1000) - accessTicks;
 
 		*timings = ((*timings) & 0x1FFFFFC00) | accessTicks | (recTicks << 5);
 	} else {
 		/* The old "ata-3" IDE controller */
-		accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time);
+		accessTicks = SYSCLK_TICKS(t->active);
 		if (accessTicks < 4)
 			accessTicks = 4;
-		recTicks = SYSCLK_TICKS(d.cycle_time) - accessTicks - 4;
+		recTicks = SYSCLK_TICKS(t->cycle) - accessTicks - 4;
 		if (recTicks < 1)
 			recTicks = 1;
 	
diff -urN linux-2.5.6/drivers/ide/ide-timing.c linux-2.5.6-timing/drivers/ide/ide-timing.c
--- linux-2.5.6/drivers/ide/ide-timing.c	Thu Jan  1 01:00:00 1970
+++ linux-2.5.6-timing/drivers/ide/ide-timing.c	Tue Mar 12 16:26:03 2002
@@ -0,0 +1,235 @@
+/*
+ * $Id: ide-timing.c,v 2.0 2002/03/12 15:48:43 vojtech Exp $
+ *
+ *  Copyright (c) 1999-2001 Vojtech Pavlik
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
+ */
+
+#include <linux/kernel.h>
+#include "ide-timing.h"
+
+/*
+ * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
+ * These were taken from ATA/ATAPI-6 standard, rev 0a, except
+ * for PIO 5, which is a nonstandard extension and UDMA6, which
+ * is currently supported only by Maxtor drives. 
+ */
+
+struct ide_timing ide_timing[] = {
+
+	{ XFER_UDMA_6,     0,   0,   0,   0,   0,   0,   0,  15 },
+	{ XFER_UDMA_5,     0,   0,   0,   0,   0,   0,   0,  20 },
+	{ XFER_UDMA_4,     0,   0,   0,   0,   0,   0,   0,  30 },
+	{ XFER_UDMA_3,     0,   0,   0,   0,   0,   0,   0,  45 },
+
+	{ XFER_UDMA_2,     0,   0,   0,   0,   0,   0,   0,  60 },
+	{ XFER_UDMA_1,     0,   0,   0,   0,   0,   0,   0,  80 },
+	{ XFER_UDMA_0,     0,   0,   0,   0,   0,   0,   0, 120 },
+
+	{ XFER_UDMA_SLOW,  0,   0,   0,   0,   0,   0,   0, 150 },
+                                          
+	{ 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_2,  60,   0,   0,   0, 120, 120, 240,   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_4,     25,  70,  25, 120,  70,  25, 120,   0 },
+	{ XFER_PIO_3,     30,  80,  70, 180,  80,  70, 180,   0 },
+
+	{ XFER_PIO_2,     30, 290,  40, 330, 100,  90, 240,   0 },
+	{ XFER_PIO_1,     50, 290,  93, 383, 125, 100, 383,   0 },
+	{ XFER_PIO_0,     70, 290, 240, 600, 165, 150, 600,   0 },
+
+	{ XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960,   0 },
+
+	{ -1 }
+};
+
+short ide_find_best_mode(ide_drive_t *drive, int map)
+{
+	struct hd_driveid *id = drive->id;
+	short best = 0;
+
+	if (!id)
+		return XFER_PIO_SLOW;
+
+	if ((map & XFER_UDMA) && (id->field_valid & 4)) {	/* Want UDMA and UDMA bitmap valid */
+
+		if ((map & XFER_UDMA_133) == XFER_UDMA_133)
+			if ((best = (id->dma_ultra & 0x0040) ? XFER_UDMA_6 : 0)) return best;
+
+		if ((map & XFER_UDMA_100) == XFER_UDMA_100)
+			if ((best = (id->dma_ultra & 0x0020) ? XFER_UDMA_5 : 0)) return best;
+
+		if ((map & XFER_UDMA_66) == XFER_UDMA_66)
+			if ((best = (id->dma_ultra & 0x0010) ? XFER_UDMA_4 :
+                	    	    (id->dma_ultra & 0x0008) ? XFER_UDMA_3 : 0)) return best;
+
+                if ((best = (id->dma_ultra & 0x0004) ? XFER_UDMA_2 :
+                	    (id->dma_ultra & 0x0002) ? XFER_UDMA_1 :
+                	    (id->dma_ultra & 0x0001) ? XFER_UDMA_0 : 0)) return best;
+	}
+
+	if ((map & XFER_MWDMA) && (id->field_valid & 2)) {	/* Want MWDMA and drive has EIDE fields */
+
+		if ((best = (id->dma_mword & 0x0004) ? XFER_MW_DMA_2 :
+                	    (id->dma_mword & 0x0002) ? XFER_MW_DMA_1 :
+                	    (id->dma_mword & 0x0001) ? XFER_MW_DMA_0 : 0)) return best;
+	}
+
+	if (map & XFER_SWDMA) {					/* Want SWDMA */
+
+ 		if (id->field_valid & 2) {			/* EIDE SWDMA */
+
+			if ((best = (id->dma_1word & 0x0004) ? XFER_SW_DMA_2 :
+      				    (id->dma_1word & 0x0002) ? XFER_SW_DMA_1 :
+				    (id->dma_1word & 0x0001) ? XFER_SW_DMA_0 : 0)) return best;
+		}
+
+		if (id->capability & 1) {			/* Pre-EIDE style SWDMA */
+
+			if ((best = (id->tDMA == 2) ? XFER_SW_DMA_2 :
+				    (id->tDMA == 1) ? XFER_SW_DMA_1 :
+				    (id->tDMA == 0) ? XFER_SW_DMA_0 : 0)) return best;
+		}
+	}
+
+
+	if ((map & XFER_EPIO) && (id->field_valid & 2)) {	/* EIDE PIO modes */
+
+		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  (drive->id->tPIO == 2) ? XFER_PIO_2 :
+		(drive->id->tPIO == 1) ? XFER_PIO_1 :
+		(drive->id->tPIO == 0) ? XFER_PIO_0 : XFER_PIO_SLOW;
+}
+
+void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int T, int UT)
+{
+	q->setup   = EZ(t->setup   * 1000,  T);
+	q->act8b   = EZ(t->act8b   * 1000,  T);
+	q->rec8b   = EZ(t->rec8b   * 1000,  T);
+	q->cyc8b   = EZ(t->cyc8b   * 1000,  T);
+	q->active  = EZ(t->active  * 1000,  T);
+	q->recover = EZ(t->recover * 1000,  T);
+	q->cycle   = EZ(t->cycle   * 1000,  T);
+	q->udma    = EZ(t->udma    * 1000, UT);
+}
+
+void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, struct ide_timing *m, unsigned int what)
+{
+	if (what & IDE_TIMING_SETUP  ) m->setup   = max(a->setup,   b->setup);
+	if (what & IDE_TIMING_ACT8B  ) m->act8b   = max(a->act8b,   b->act8b);
+	if (what & IDE_TIMING_REC8B  ) m->rec8b   = max(a->rec8b,   b->rec8b);
+	if (what & IDE_TIMING_CYC8B  ) m->cyc8b   = max(a->cyc8b,   b->cyc8b);
+	if (what & IDE_TIMING_ACTIVE ) m->active  = max(a->active,  b->active);
+	if (what & IDE_TIMING_RECOVER) m->recover = max(a->recover, b->recover);
+	if (what & IDE_TIMING_CYCLE  ) m->cycle   = max(a->cycle,   b->cycle);
+	if (what & IDE_TIMING_UDMA   ) m->udma    = max(a->udma,    b->udma);
+}
+
+struct ide_timing* ide_timing_find_mode(short speed)
+{
+	struct ide_timing *t;
+
+	for (t = ide_timing; t->mode != speed; t++)
+		if (t->mode < 0)
+			return NULL;
+	return t; 
+}
+
+int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing *t, int T, int UT)
+{
+	struct hd_driveid *id = drive->id;
+	struct ide_timing *s, p;
+
+/*
+ * Find the mode.
+ */
+
+	if (!(s = ide_timing_find_mode(speed)))
+		return -EINVAL;
+
+/*
+ * If the drive is an EIDE drive, it can tell us it needs extended
+ * PIO/MWDMA cycle timing.
+ */
+
+	if (id && id->field_valid & 2) {	/* EIDE drive */
+
+		memset(&p, 0, sizeof(p));
+
+		switch (speed & XFER_MODE) {
+
+			case XFER_PIO:
+				if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = id->eide_pio;
+						    else p.cycle = p.cyc8b = id->eide_pio_iordy;
+				break;
+
+			case XFER_MWDMA:
+				p.cycle = id->eide_dma_min;
+				break;
+		}
+
+		ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B);
+	}
+
+/*
+ * Convert the timing to bus clock counts.
+ */
+
+	ide_timing_quantize(s, t, T, UT);
+
+/*
+ * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
+ * and some other commands. We have to ensure that the DMA cycle timing is
+ * slower/equal than the fastest PIO timing.
+ */
+
+	if ((speed & XFER_MODE) != XFER_PIO) {
+		ide_timing_compute(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO), &p, T, UT);
+		ide_timing_merge(&p, t, t, IDE_TIMING_ALL);
+	}
+
+/*
+ * Lenghten active & recovery time so that cycle time is correct.
+ */
+
+	if (t->act8b + t->rec8b < t->cyc8b) {
+		t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2;
+		t->rec8b = t->cyc8b - t->act8b;
+	}
+
+	if (t->active + t->recover < t->cycle) {
+		t->active += (t->cycle - (t->active + t->recover)) / 2;
+		t->recover = t->cycle - t->active;
+	}
+
+	return 0;
+}
diff -urN linux-2.5.6/drivers/ide/ide-timing.h linux-2.5.6-timing/drivers/ide/ide-timing.h
--- linux-2.5.6/drivers/ide/ide-timing.h	Wed Feb 20 03:11:04 2002
+++ linux-2.5.6-timing/drivers/ide/ide-timing.h	Tue Mar 12 16:29:03 2002
@@ -1,10 +1,11 @@
-#ifndef _IDE_TIMING_H
-#define _IDE_TIMING_H
+#ifndef _IDE_MODES_H
+#define _IDE_MODES_H
 
 /*
- * $Id: ide-timing.h,v 1.6 2001/12/23 22:47:56 vojtech Exp $
+ * $Id: ide-timing.h,v 2.0 2002/03/12 13:02:22 vojtech Exp $
  *
- *  Copyright (c) 1999-2001 Vojtech Pavlik
+ *  Copyright (C) 1996  Linus Torvalds, Igor Abramov, and Mark Lord
+ *  Copyright (C) 1999-2001 Vojtech Pavlik
  */
 
 /*
@@ -21,13 +22,10 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
 #include <linux/hdreg.h>
+#include <linux/ide.h>
 
 #define XFER_PIO_5		0x0d
 #define XFER_UDMA_SLOW		0x4f
@@ -44,46 +42,7 @@
 	short udma;	/* t2CYCTYP/2 */
 };
 
-/*
- * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
- * These were taken from ATA/ATAPI-6 standard, rev 0a, except
- * for PIO 5, which is a nonstandard extension and UDMA6, which
- * is currently supported only by Maxtor drives. 
- */
-
-static struct ide_timing ide_timing[] = {
-
-	{ XFER_UDMA_6,     0,   0,   0,   0,   0,   0,   0,  15 },
-	{ XFER_UDMA_5,     0,   0,   0,   0,   0,   0,   0,  20 },
-	{ XFER_UDMA_4,     0,   0,   0,   0,   0,   0,   0,  30 },
-	{ XFER_UDMA_3,     0,   0,   0,   0,   0,   0,   0,  45 },
-
-	{ XFER_UDMA_2,     0,   0,   0,   0,   0,   0,   0,  60 },
-	{ XFER_UDMA_1,     0,   0,   0,   0,   0,   0,   0,  80 },
-	{ XFER_UDMA_0,     0,   0,   0,   0,   0,   0,   0, 120 },
-
-	{ XFER_UDMA_SLOW,  0,   0,   0,   0,   0,   0,   0, 150 },
-                                          
-	{ 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_2,  60,   0,   0,   0, 120, 120, 240,   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_4,     25,  70,  25, 120,  70,  25, 120,   0 },
-	{ XFER_PIO_3,     30,  80,  70, 180,  80,  70, 180,   0 },
-
-	{ XFER_PIO_2,     30, 290,  40, 330, 100,  90, 240,   0 },
-	{ XFER_PIO_1,     50, 290,  93, 383, 125, 100, 383,   0 },
-	{ XFER_PIO_0,     70, 290, 240, 600, 165, 150, 600,   0 },
-
-	{ XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960,   0 },
-
-	{ -1 }
-};
+extern struct ide_timing ide_timing[];
 
 #define IDE_TIMING_SETUP	0x01
 #define IDE_TIMING_ACT8B	0x02
@@ -96,9 +55,7 @@
 #define IDE_TIMING_UDMA		0x80
 #define IDE_TIMING_ALL		0xff
 
-#define MIN(a,b)	((a)<(b)?(a):(b))
-#define MAX(a,b)	((a)>(b)?(a):(b))
-#define FIT(v,min,max)	MAX(MIN(v,max),min)
+#define FIT(v,x,y)	max_t(int,min_t(int,v,x),y)
 #define ENOUGH(v,unit)	(((v)-1)/(unit)+1)
 #define EZ(v,unit)	((v)?ENOUGH(v,unit):0)
 
@@ -112,170 +69,20 @@
 #define XFER_EPIO	0x01
 #define XFER_PIO	0x00
 
-static short ide_find_best_mode(ide_drive_t *drive, int map)
-{
-	struct hd_driveid *id = drive->id;
-	short best = 0;
-
-	if (!id)
-		return XFER_PIO_SLOW;
-
-	if ((map & XFER_UDMA) && (id->field_valid & 4)) {	/* Want UDMA and UDMA bitmap valid */
-
-		if ((map & XFER_UDMA_133) == XFER_UDMA_133)
-			if ((best = (id->dma_ultra & 0x0040) ? XFER_UDMA_6 : 0)) return best;
-
-		if ((map & XFER_UDMA_100) == XFER_UDMA_100)
-			if ((best = (id->dma_ultra & 0x0020) ? XFER_UDMA_5 : 0)) return best;
-
-		if ((map & XFER_UDMA_66) == XFER_UDMA_66)
-			if ((best = (id->dma_ultra & 0x0010) ? XFER_UDMA_4 :
-                	    	    (id->dma_ultra & 0x0008) ? XFER_UDMA_3 : 0)) return best;
-
-                if ((best = (id->dma_ultra & 0x0004) ? XFER_UDMA_2 :
-                	    (id->dma_ultra & 0x0002) ? XFER_UDMA_1 :
-                	    (id->dma_ultra & 0x0001) ? XFER_UDMA_0 : 0)) return best;
-	}
-
-	if ((map & XFER_MWDMA) && (id->field_valid & 2)) {	/* Want MWDMA and drive has EIDE fields */
-
-		if ((best = (id->dma_mword & 0x0004) ? XFER_MW_DMA_2 :
-                	    (id->dma_mword & 0x0002) ? XFER_MW_DMA_1 :
-                	    (id->dma_mword & 0x0001) ? XFER_MW_DMA_0 : 0)) return best;
-	}
-
-	if (map & XFER_SWDMA) {					/* Want SWDMA */
-
- 		if (id->field_valid & 2) {			/* EIDE SWDMA */
-
-			if ((best = (id->dma_1word & 0x0004) ? XFER_SW_DMA_2 :
-      				    (id->dma_1word & 0x0002) ? XFER_SW_DMA_1 :
-				    (id->dma_1word & 0x0001) ? XFER_SW_DMA_0 : 0)) return best;
-		}
-
-		if (id->capability & 1) {			/* Pre-EIDE style SWDMA */
-
-			if ((best = (id->tDMA == 2) ? XFER_SW_DMA_2 :
-				    (id->tDMA == 1) ? XFER_SW_DMA_1 :
-				    (id->tDMA == 0) ? XFER_SW_DMA_0 : 0)) return best;
-		}
-	}
-
-
-	if ((map & XFER_EPIO) && (id->field_valid & 2)) {	/* EIDE PIO modes */
-
-		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  (drive->id->tPIO == 2) ? XFER_PIO_2 :
-		(drive->id->tPIO == 1) ? XFER_PIO_1 :
-		(drive->id->tPIO == 0) ? XFER_PIO_0 : XFER_PIO_SLOW;
-}
-
-static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int T, int UT)
-{
-	q->setup   = EZ(t->setup   * 1000,  T);
-	q->act8b   = EZ(t->act8b   * 1000,  T);
-	q->rec8b   = EZ(t->rec8b   * 1000,  T);
-	q->cyc8b   = EZ(t->cyc8b   * 1000,  T);
-	q->active  = EZ(t->active  * 1000,  T);
-	q->recover = EZ(t->recover * 1000,  T);
-	q->cycle   = EZ(t->cycle   * 1000,  T);
-	q->udma    = EZ(t->udma    * 1000, UT);
-}
-
-static void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, struct ide_timing *m, unsigned int what)
-{
-	if (what & IDE_TIMING_SETUP  ) m->setup   = MAX(a->setup,   b->setup);
-	if (what & IDE_TIMING_ACT8B  ) m->act8b   = MAX(a->act8b,   b->act8b);
-	if (what & IDE_TIMING_REC8B  ) m->rec8b   = MAX(a->rec8b,   b->rec8b);
-	if (what & IDE_TIMING_CYC8B  ) m->cyc8b   = MAX(a->cyc8b,   b->cyc8b);
-	if (what & IDE_TIMING_ACTIVE ) m->active  = MAX(a->active,  b->active);
-	if (what & IDE_TIMING_RECOVER) m->recover = MAX(a->recover, b->recover);
-	if (what & IDE_TIMING_CYCLE  ) m->cycle   = MAX(a->cycle,   b->cycle);
-	if (what & IDE_TIMING_UDMA   ) m->udma    = MAX(a->udma,    b->udma);
-}
-
-static struct ide_timing* ide_timing_find_mode(short speed)
-{
-	struct ide_timing *t;
-
-	for (t = ide_timing; t->mode != speed; t++)
-		if (t->mode < 0)
-			return NULL;
-	return t; 
-}
-
-static int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing *t, int T, int UT)
-{
-	struct hd_driveid *id = drive->id;
-	struct ide_timing *s, p;
-
-/*
- * Find the mode.
- */
-
-	if (!(s = ide_timing_find_mode(speed)))
-		return -EINVAL;
-
-/*
- * If the drive is an EIDE drive, it can tell us it needs extended
- * PIO/MWDMA cycle timing.
- */
-
-	if (id && id->field_valid & 2) {	/* EIDE drive */
-
-		memset(&p, 0, sizeof(p));
-
-		switch (speed & XFER_MODE) {
-
-			case XFER_PIO:
-				if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = id->eide_pio;
-						    else p.cycle = p.cyc8b = id->eide_pio_iordy;
-				break;
-
-			case XFER_MWDMA:
-				p.cycle = id->eide_dma_min;
-				break;
-		}
-
-		ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B);
-	}
+extern short ide_find_best_mode(ide_drive_t *drive, int map);
+extern void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int T, int UT);
+extern void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, struct ide_timing *m, unsigned int what);
+extern struct ide_timing* ide_timing_find_mode(short speed);
+extern int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing *t, int T, int UT);
 
 /*
- * Convert the timing to bus clock counts.
+ * Backward compatibility stuff.
  */
 
-	ide_timing_quantize(s, t, T, UT);
-
-/*
- * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
- * and some other commands. We have to ensure that the DMA cycle timing is
- * slower/equal than the fastest PIO timing.
- */
-
-	if ((speed & XFER_MODE) != XFER_PIO) {
-		ide_timing_compute(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO), &p, T, UT);
-		ide_timing_merge(&p, t, t, IDE_TIMING_ALL);
-	}
-
-/*
- * Lenghten active & recovery time so that cycle time is correct.
- */
-
-	if (t->act8b + t->rec8b < t->cyc8b) {
-		t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2;
-		t->rec8b = t->cyc8b - t->act8b;
-	}
-
-	if (t->active + t->recover < t->cycle) {
-		t->active += (t->cycle - (t->active + t->recover)) / 2;
-		t->recover = t->cycle - t->active;
-	}
-
-	return 0;
-}
+typedef struct ide_pio_timings_s {
+	int	setup_time;	/* Address setup (ns) minimum */
+	int	active_time;	/* Active pulse (ns) minimum */
+	int	cycle_time;	/* Cycle time (ns) minimum = (setup + active + recovery) */
+} ide_pio_timings_t;
 
 #endif
diff -urN linux-2.5.6/drivers/ide/ide.c linux-2.5.6-timing/drivers/ide/ide.c
--- linux-2.5.6/drivers/ide/ide.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/ide.c	Tue Mar 12 16:26:03 2002
@@ -149,7 +149,7 @@
 #include <asm/io.h>
 #include <asm/bitops.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 /*
  * Those will be moved into separate header files eventually.
@@ -194,94 +194,6 @@
 extern void pnpide_init(int);
 #endif
 
-/*
- * Constant tables for PIO mode programming:
- */
-const ide_pio_timings_t ide_pio_timings[6] = {
-	{ 70,	165,	600 },	/* PIO Mode 0 */
-	{ 50,	125,	383 },	/* PIO Mode 1 */
-	{ 30,	100,	240 },	/* PIO Mode 2 */
-	{ 30,	80,	180 },	/* PIO Mode 3 with IORDY */
-	{ 25,	70,	120 },	/* PIO Mode 4 with IORDY */
-	{ 20,	50,	100 }	/* PIO Mode 5 with IORDY (nonstandard) */
-};
-
-/*
- * Black list. Some drives incorrectly report their maximal PIO mode,
- * at least in respect to CMD640. Here we keep info on some known drives.
- */
-static struct ide_pio_info {
-	const char	*name;
-	int		pio;
-} ide_pio_blacklist[] = {
-/*	{ "Conner Peripherals 1275MB - CFS1275A", 4 }, */
-	{ "Conner Peripherals 540MB - CFS540A", 3 },
-
-	{ "WDC AC2700",  3 },
-	{ "WDC AC2540",  3 },
-	{ "WDC AC2420",  3 },
-	{ "WDC AC2340",  3 },
-	{ "WDC AC2250",  0 },
-	{ "WDC AC2200",  0 },
-	{ "WDC AC21200", 4 },
-	{ "WDC AC2120",  0 },
-	{ "WDC AC2850",  3 },
-	{ "WDC AC1270",  3 },
-	{ "WDC AC1170",  1 },
-	{ "WDC AC1210",  1 },
-	{ "WDC AC280",   0 },
-/*	{ "WDC AC21000", 4 }, */
-	{ "WDC AC31000", 3 },
-	{ "WDC AC31200", 3 },
-/*	{ "WDC AC31600", 4 }, */
-
-	{ "Maxtor 7131 AT", 1 },
-	{ "Maxtor 7171 AT", 1 },
-	{ "Maxtor 7213 AT", 1 },
-	{ "Maxtor 7245 AT", 1 },
-	{ "Maxtor 7345 AT", 1 },
-	{ "Maxtor 7546 AT", 3 },
-	{ "Maxtor 7540 AV", 3 },
-
-	{ "SAMSUNG SHD-3121A", 1 },
-	{ "SAMSUNG SHD-3122A", 1 },
-	{ "SAMSUNG SHD-3172A", 1 },
-
-/*	{ "ST51080A", 4 },
- *	{ "ST51270A", 4 },
- *	{ "ST31220A", 4 },
- *	{ "ST31640A", 4 },
- *	{ "ST32140A", 4 },
- *	{ "ST3780A",  4 },
- */
-	{ "ST5660A",  3 },
-	{ "ST3660A",  3 },
-	{ "ST3630A",  3 },
-	{ "ST3655A",  3 },
-	{ "ST3391A",  3 },
-	{ "ST3390A",  1 },
-	{ "ST3600A",  1 },
-	{ "ST3290A",  0 },
-	{ "ST3144A",  0 },
-	{ "ST3491A",  1 },	/* reports 3, should be 1 or 2 (depending on
-				 * drive) according to Seagates FIND-ATA program */
-
-	{ "QUANTUM ELS127A", 0 },
-	{ "QUANTUM ELS170A", 0 },
-	{ "QUANTUM LPS240A", 0 },
-	{ "QUANTUM LPS210A", 3 },
-	{ "QUANTUM LPS270A", 3 },
-	{ "QUANTUM LPS365A", 3 },
-	{ "QUANTUM LPS540A", 3 },
-	{ "QUANTUM LIGHTNING 540A", 3 },
-	{ "QUANTUM LIGHTNING 730A", 3 },
-
-        { "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */
-        { "QUANTUM FIREBALL_640", 3 },
-        { "QUANTUM FIREBALL_1080", 3 },
-        { "QUANTUM FIREBALL_1280", 3 },
-	{ NULL,	0 }
-};
 
 /* default maximum number of failures */
 #define IDE_DEFAULT_MAX_FAILURES	1
@@ -314,105 +226,6 @@
  */
 ide_hwif_t ide_hwifs[MAX_HWIFS];	/* master data repository */
 
-
-/*
- * This routine searches the ide_pio_blacklist for an entry
- * matching the start/whole of the supplied model name.
- *
- * Returns -1 if no match found.
- * Otherwise returns the recommended PIO mode from ide_pio_blacklist[].
- */
-int ide_scan_pio_blacklist (char *model)
-{
-	struct ide_pio_info *p;
-
-	for (p = ide_pio_blacklist; p->name != NULL; p++) {
-		if (strncmp(p->name, model, strlen(p->name)) == 0)
-			return p->pio;
-	}
-	return -1;
-}
-
-/*
- * This routine returns the recommended PIO settings for a given drive,
- * based on the drive->id information and the ide_pio_blacklist[].
- * This is used by most chipset support modules when "auto-tuning".
- */
-
-/*
- * Drive PIO mode auto selection
- */
-byte ide_get_best_pio_mode (ide_drive_t *drive, byte mode_wanted, byte max_mode, ide_pio_data_t *d)
-{
-	int pio_mode;
-	int cycle_time = 0;
-	int use_iordy = 0;
-	struct hd_driveid* id = drive->id;
-	int overridden  = 0;
-	int blacklisted = 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) {
-		overridden = 1;
-		blacklisted = 1;
-		use_iordy = (pio_mode > 2);
-	} else {
-		pio_mode = id->tPIO;
-		if (pio_mode > 2) {	/* 2 is maximum allowed tPIO value */
-			pio_mode = 2;
-			overridden = 1;
-		}
-		if (id->field_valid & 2) {	  /* drive implements ATA2? */
-			if (id->capability & 8) { /* drive supports use_iordy? */
-				use_iordy = 1;
-				cycle_time = id->eide_pio_iordy;
-				if (id->eide_pio_modes & 7) {
-					overridden = 0;
-					if (id->eide_pio_modes & 4)
-						pio_mode = 5;
-					else if (id->eide_pio_modes & 2)
-						pio_mode = 4;
-					else
-						pio_mode = 3;
-				}
-			} else {
-				cycle_time = id->eide_pio;
-			}
-		}
-
-#if 0
-		if (drive->id->major_rev_num & 0x0004) printk("ATA-2 ");
-#endif
-
-		/*
-		 * Conservative "downgrade" for all pre-ATA2 drives
-		 */
-		if (pio_mode && pio_mode < 4) {
-			pio_mode--;
-			overridden = 1;
-#if 0
-			use_iordy = (pio_mode > 2);
-#endif
-			if (cycle_time && cycle_time < ide_pio_timings[pio_mode].cycle_time)
-				cycle_time = 0; /* use standard timing */
-		}
-	}
-	if (pio_mode > max_mode) {
-		pio_mode = max_mode;
-		cycle_time = 0;
-	}
-	if (d) {
-		d->pio_mode = pio_mode;
-		d->cycle_time = cycle_time ? cycle_time : ide_pio_timings[pio_mode].cycle_time;
-		d->use_iordy = use_iordy;
-		d->overridden = overridden;
-		d->blacklisted = blacklisted;
-	}
-	return pio_mode;
-}
 
 #if (DISK_RECOVERY_TIME > 0)
 /*
diff -urN linux-2.5.6/drivers/ide/ide_modes.h linux-2.5.6-timing/drivers/ide/ide_modes.h
--- linux-2.5.6/drivers/ide/ide_modes.h	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/ide_modes.h	Thu Jan  1 01:00:00 1970
@@ -1,42 +0,0 @@
-/*
- *  linux/drivers/ide/ide_modes.h
- *
- *  Copyright (C) 1996  Linus Torvalds, Igor Abramov, and Mark Lord
- */
-
-#ifndef _IDE_MODES_H
-#define _IDE_MODES_H
-
-#include <linux/config.h>
-
-/*
- * Shared data/functions for determining best PIO mode for an IDE drive.
- */
-
-#ifdef CONFIG_BLK_DEV_IDE_MODES
-
-/*
- * Standard (generic) timings for PIO modes, from ATA2 specification.
- * These timings are for access to the IDE data port register *only*.
- * Some drives may specify a mode, while also specifying a different
- * value for cycle_time (from drive identification data).
- */
-typedef struct ide_pio_timings_s {
-	int	setup_time;	/* Address setup (ns) minimum */
-	int	active_time;	/* Active pulse (ns) minimum */
-	int	cycle_time;	/* Cycle time (ns) minimum = (setup + active + recovery) */
-} ide_pio_timings_t;
-
-typedef struct ide_pio_data_s {
-	byte pio_mode;
-	byte use_iordy;
-	byte overridden;
-	byte blacklisted;
-	unsigned int cycle_time;
-} ide_pio_data_t;
-
-extern int ide_scan_pio_blacklist (char *model);
-extern byte ide_get_best_pio_mode (ide_drive_t *drive, byte mode_wanted, byte max_mode, ide_pio_data_t *d);
-extern const ide_pio_timings_t ide_pio_timings[6];
-#endif
-#endif
diff -urN linux-2.5.6/drivers/ide/it8172.c linux-2.5.6-timing/drivers/ide/it8172.c
--- linux-2.5.6/drivers/ide/it8172.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/it8172.c	Tue Mar 12 16:26:03 2002
@@ -41,7 +41,7 @@
 #include <asm/io.h>
 #include <asm/it8172/it8172_int.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 /*
  * Prototypes
@@ -65,7 +65,11 @@
     int master_port	= 0x40;
     int slave_port      = 0x44;
     
-    pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
+    if (pio == 255)
+	pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
+    else
+       pio = min_t(byte, pio, 4);
+
     pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
     pci_read_config_dword(HWIF(drive)->pci_dev, slave_port, &slave_data);
 
@@ -186,25 +190,7 @@
     struct hd_driveid *id = drive->id;
     byte speed;
 
-    if (id->dma_ultra & 0x0010) {
-	speed = XFER_UDMA_2;
-    } else if (id->dma_ultra & 0x0008) {
-	speed = XFER_UDMA_1;
-    } else if (id->dma_ultra & 0x0004) {
-	speed = XFER_UDMA_2;
-    } else if (id->dma_ultra & 0x0002) {
-	speed = XFER_UDMA_1;
-    } else if (id->dma_ultra & 0x0001) {
-	speed = XFER_UDMA_0;
-    } else if (id->dma_mword & 0x0004) {
-	speed = XFER_MW_DMA_2;
-    } else if (id->dma_mword & 0x0002) {
-	speed = XFER_MW_DMA_1;
-    } else if (id->dma_1word & 0x0004) {
-	speed = XFER_SW_DMA_2;
-    } else {
-	speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
-    }
+    speed = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_UDMA);
 
     (void) it8172_tune_chipset(drive, speed);
 
diff -urN linux-2.5.6/drivers/ide/opti621.c linux-2.5.6-timing/drivers/ide/opti621.c
--- linux-2.5.6/drivers/ide/opti621.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/opti621.c	Tue Mar 12 16:26:03 2002
@@ -97,7 +97,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #define OPTI621_MAX_PIO 3
 /* In fact, I do not have any PIO 4 drive
@@ -144,12 +144,16 @@
 	int d;
 	ide_hwif_t *hwif = HWIF(drive);
 
-	drive->drive_data = ide_get_best_pio_mode(drive, pio, OPTI621_MAX_PIO, NULL);
+	if (pio == PIO_DONT_KNOW)
+		drive->drive_data = min(ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0, OPTI621_MAX_PIO);
+	else
+		drive->drive_data = pio;
+		
 	for (d = 0; d < 2; ++d) {
 		drive = &hwif->drives[d];
 		if (drive->present) {
 			if (drive->drive_data == PIO_DONT_KNOW)
-				drive->drive_data = ide_get_best_pio_mode(drive, 255, OPTI621_MAX_PIO, NULL);
+				drive->drive_data = min(ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0, OPTI621_MAX_PIO);
 #ifdef OPTI621_DEBUG
 			printk("%s: Selected PIO mode %d\n", drive->name, drive->drive_data);
 #endif
diff -urN linux-2.5.6/drivers/ide/pdc202xx.c linux-2.5.6-timing/drivers/ide/pdc202xx.c
--- linux-2.5.6/drivers/ide/pdc202xx.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/pdc202xx.c	Tue Mar 12 16:26:03 2002
@@ -46,7 +46,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #define PDC202XX_DEBUG_DRIVE_INFO		0
 #define PDC202XX_DECODE_REGISTER_INFO		0
@@ -681,8 +681,10 @@
 {
 	byte speed = 0x00;
 
-	pio = (pio == 5) ? 4 : pio;
-	speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL);
+	if (pio == 255)
+		speed = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
+	else
+		speed = XFER_PIO_0 + min_t(byte, pio, 4);
         
 	return ((int) pdc202xx_tune_chipset(drive, speed));
 }
diff -urN linux-2.5.6/drivers/ide/pdcadma.c linux-2.5.6-timing/drivers/ide/pdcadma.c
--- linux-2.5.6/drivers/ide/pdcadma.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/pdcadma.c	Tue Mar 12 16:26:03 2002
@@ -24,7 +24,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #undef DISPLAY_PDCADMA_TIMINGS
 
diff -urN linux-2.5.6/drivers/ide/piix.c linux-2.5.6-timing/drivers/ide/piix.c
--- linux-2.5.6/drivers/ide/piix.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/piix.c	Tue Mar 12 16:26:03 2002
@@ -65,7 +65,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #define PIIX_DEBUG_DRIVE_INFO		0
 
@@ -225,7 +225,11 @@
 				    { 2, 1 },
 				    { 2, 3 }, };
 
-	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
+	if (pio == 255)
+		pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
+	else
+		pio = min_t(byte, pio, 4);
+
 	pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
 	if (is_slave) {
 		master_data = master_data | 0x4000;
@@ -352,27 +356,9 @@
 				   (dev->device == PCI_DEVICE_ID_INTEL_82451NX) ||
 				   (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1)) ? 1 : 0;
 
-	if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) {
-		speed = XFER_UDMA_5;
-	} else if ((id->dma_ultra & 0x0010) && (ultra)) {
-		speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2;
-	} else if ((id->dma_ultra & 0x0008) && (ultra)) {
-		speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1;
-	} else if ((id->dma_ultra & 0x0004) && (ultra)) {
-		speed = XFER_UDMA_2;
-	} else if ((id->dma_ultra & 0x0002) && (ultra)) {
-		speed = XFER_UDMA_1;
-	} else if ((id->dma_ultra & 0x0001) && (ultra)) {
-		speed = XFER_UDMA_0;
-	} else if (id->dma_mword & 0x0004) {
-		speed = XFER_MW_DMA_2;
-	} else if (id->dma_mword & 0x0002) {
-		speed = XFER_MW_DMA_1;
-	} else if (id->dma_1word & 0x0004) {
-		speed = XFER_SW_DMA_2;
-        } else {
-		speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
-	}
+	speed = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA
+					| (ultra ? XFER_UDMA : 0) | ((udma_66 & ultra66) ? XFER_UDMA_66 : 0)
+					| ((udma_66 & ultra100) ? XFER_UDMA_100 : 0));
 
 	(void) piix_tune_chipset(drive, speed);
 
@@ -385,7 +371,7 @@
 
 static void config_chipset_for_pio (ide_drive_t *drive)
 {
-	piix_tune_drive(drive, ide_get_best_pio_mode(drive, 255, 5, NULL));
+	piix_tune_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0);
 }
 
 static int config_drive_xfer_rate (ide_drive_t *drive)
diff -urN linux-2.5.6/drivers/ide/qd65xx.c linux-2.5.6-timing/drivers/ide/qd65xx.c
--- linux-2.5.6/drivers/ide/qd65xx.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/qd65xx.c	Tue Mar 12 16:26:03 2002
@@ -33,7 +33,7 @@
 #include <linux/init.h>
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 #include "qd65xx.h"
 
 /*
@@ -249,42 +249,46 @@
 
 static void qd6580_tune_drive (ide_drive_t *drive, byte pio)
 {
-	ide_pio_data_t d;
+	struct ide_timing *t;
 	int base = HWIF(drive)->select_data;
 	int active_time   = 175;
 	int recovery_time = 415; /* worst case values from the dos driver */
 
 	if (drive->id && !qd_find_disk_type(drive,&active_time,&recovery_time)) {
-		pio = ide_get_best_pio_mode(drive, pio, 255, &d);
-		pio = min(pio,4);
+
+		if (pio == 255)
+			pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
+		else
+			pio = XFER_PIO_0 + min_t(byte, pio, 4);
+
+		t = ide_timing_find_mode(pio);
 
 		switch (pio) {
 			case 0: break;
 			case 3:
-				if (d.cycle_time >= 110) {
+				if (t->cycle >= 110) {
 					active_time = 86;
-					recovery_time = d.cycle_time-102;
+					recovery_time = t->cycle-102;
 				} else
 					printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name);
 				break;
 			case 4:
-				if (d.cycle_time >= 69) {
+				if (t->cycle >= 69) {
 					active_time = 70;
-					recovery_time = d.cycle_time-61;
+					recovery_time = t->cycle-61;
 				} else
 					printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name);
 				break;
 			default:
-				if (d.cycle_time >= 180) {
+				if (t->cycle >= 180) {
 					active_time = 110;
-					recovery_time = d.cycle_time - 120;
+					recovery_time = t->cycle - 120;
 				} else {
-					active_time = ide_pio_timings[pio].active_time;
-					recovery_time = d.cycle_time
-							-active_time;
+					active_time = t->active;
+					recovery_time = t->cycle - active_time;
 				}
 		}
-		printk(KERN_INFO "%s: PIO mode%d\n",drive->name,pio);
+		printk(KERN_INFO "%s: PIO mode%d\n", drive->name, pio - XFER_PIO_0);
 	}
 
 	if (!HWIF(drive)->channel && drive->type != ATA_DISK) {
diff -urN linux-2.5.6/drivers/ide/serverworks.c linux-2.5.6-timing/drivers/ide/serverworks.c
--- linux-2.5.6/drivers/ide/serverworks.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/serverworks.c	Tue Mar 12 16:26:03 2002
@@ -91,7 +91,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #define DISPLAY_SVWKS_TIMINGS	1
 #undef SVWKS_DEBUG_DRIVE_INFO
@@ -263,7 +263,7 @@
 	byte pio_timing		= 0x00;
 	unsigned short csb5_pio	= 0x00;
 
-	byte pio	= ide_get_best_pio_mode(drive, 255, 5, NULL);
+	byte pio	= ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 
         switch (drive->dn) {
 		case 0: drive_pci = 0x41; drive_pci2 = 0x45; break;
@@ -364,9 +364,9 @@
 	unsigned short xfer_pio = drive->id->eide_pio_modes;
 	byte timing, speed, pio;
 
-	pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
+	pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 
-	if (xfer_pio> 4)
+	if (xfer_pio > 4)
 		xfer_pio = 0;
 
 	if (drive->id->eide_pio_iordy > 0)
@@ -417,29 +417,10 @@
 	byte udma_66	= eighty_ninty_three(drive);
 	int ultra66	= (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ? 1 : 0;
 	int ultra100 	= (ultra66 && svwks_revision >= SVWKS_CSB5_REVISION_NEW) ? 1 : 0;
-	byte speed;
 
-	if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) {
-		speed = XFER_UDMA_5;
-	} else if (id->dma_ultra & 0x0010) {
-		speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2;
-	} else if (id->dma_ultra & 0x0008) {
-		speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1;
-	} else if (id->dma_ultra & 0x0004) {
-		speed = XFER_UDMA_2;
-	} else if (id->dma_ultra & 0x0002) {
-		speed = XFER_UDMA_1;
-	} else if (id->dma_ultra & 0x0001) {
-		speed = XFER_UDMA_0;
-	} else if (id->dma_mword & 0x0004) {
-		speed = XFER_MW_DMA_2;
-	} else if (id->dma_mword & 0x0002) {
-		speed = XFER_MW_DMA_1;
-	} else if (id->dma_1word & 0x0004) {
-		speed = XFER_SW_DMA_2;
-	} else {
-		speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
-	}
+	byte speed = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_UDMA
+				| ((udma_66 && ultra66) ? XFER_UDMA_66 : 0)
+				| ((udma_66 && ultra100) ? XFER_UDMA_100 : 0));
 
 	(void) svwks_tune_chipset(drive, speed);
 
diff -urN linux-2.5.6/drivers/ide/sis5513.c linux-2.5.6-timing/drivers/ide/sis5513.c
--- linux-2.5.6/drivers/ide/sis5513.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/sis5513.c	Tue Mar 12 16:26:03 2002
@@ -26,7 +26,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #define DISPLAY_SIS_TIMINGS
 #define SIS5513_DEBUG_DRIVE_INFO	0
@@ -256,7 +256,9 @@
 	unsigned short xfer_pio = drive->id->eide_pio_modes;
 
 	config_drive_art_rwp(drive);
-	pio = ide_get_best_pio_mode(drive, 255, pio, NULL);
+	
+	if (pio == 255)
+		pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 
 	if (xfer_pio> 4)
 		xfer_pio = 0;
diff -urN linux-2.5.6/drivers/ide/sl82c105.c linux-2.5.6-timing/drivers/ide/sl82c105.c
--- linux-2.5.6/drivers/ide/sl82c105.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/sl82c105.c	Tue Mar 12 16:26:03 2002
@@ -22,7 +22,7 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 extern char *ide_xfer_verbose (byte xfer_rate);
 
@@ -31,13 +31,13 @@
  * times for the interface.  This has protection against run-away
  * timings.
  */
-static unsigned int get_timing_sl82c105(ide_pio_data_t *p)
+static unsigned int get_timing_sl82c105(struct ide_timing *t)
 {
 	unsigned int cmd_on;
 	unsigned int cmd_off;
 
-	cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30;
-	cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30;
+	cmd_on = (t->active + 29) / 30;
+	cmd_off = (t->cycle - 30 * cmd_on + 29) / 30;
 
 	if (cmd_on > 32)
 		cmd_on = 32;
@@ -49,7 +49,7 @@
 	if (cmd_off == 0)
 		cmd_off = 1;
 
-	return (cmd_on - 1) << 8 | (cmd_off - 1) | (p->use_iordy ? 0x40 : 0x00);
+	return (cmd_on - 1) << 8 | (cmd_off - 1) | ((t->mode > XFER_PIO_2) ? 0x40 : 0x00);
 }
 
 /*
@@ -59,25 +59,21 @@
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	struct pci_dev *dev = hwif->pci_dev;
-	ide_pio_data_t p;
+	struct ide_timing *t;
 	unsigned short drv_ctrl = 0x909;
 	unsigned int xfer_mode, reg;
 
 	reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);
 
-	pio = ide_get_best_pio_mode(drive, pio, 5, &p);
+	if (pio == 255)
+		xfer_mode = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
+	else
+		xfer_mode = XFER_PIO_0 + min_t(byte, pio, 4);
 
-	switch (pio) {
-	default:
-	case 0:		xfer_mode = XFER_PIO_0;		break;
-	case 1:		xfer_mode = XFER_PIO_1;		break;
-	case 2:		xfer_mode = XFER_PIO_2;		break;
-	case 3:		xfer_mode = XFER_PIO_3;		break;
-	case 4:		xfer_mode = XFER_PIO_4;		break;
-	}
+	t = ide_timing_find_mode(xfer_mode);
 
 	if (ide_config_drive_speed(drive, xfer_mode) == 0)
-		drv_ctrl = get_timing_sl82c105(&p);
+		drv_ctrl = get_timing_sl82c105(t);
 
 	if (drive->using_dma == 0) {
 		/*
@@ -89,7 +85,7 @@
 
 		if (report) {
 			printk("%s: selected %s (%dns) (%04X)\n", drive->name,
-			       ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl);
+			       ide_xfer_verbose(xfer_mode), t->cycle, drv_ctrl);
 		}
 	}
 }
diff -urN linux-2.5.6/drivers/ide/slc90e66.c linux-2.5.6-timing/drivers/ide/slc90e66.c
--- linux-2.5.6/drivers/ide/slc90e66.c	Mon Mar 11 08:46:22 2002
+++ linux-2.5.6-timing/drivers/ide/slc90e66.c	Tue Mar 12 16:26:03 2002
@@ -48,7 +48,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 #define SLC90E66_DEBUG_DRIVE_INFO		0
 
@@ -202,7 +202,11 @@
 				    { 2, 1 },
 				    { 2, 3 }, };
 
-	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
+	if (pio == 255)
+		pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
+	else
+		pio = min_t(byte, pio, 4);
+
 	pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
 	if (is_slave) {
 		master_data = master_data | 0x4000;
@@ -299,30 +303,14 @@
 
 #if 1 /* allow PIO modes */
 	if (!HWIF(drive)->autodma) {
-		speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
+		speed = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
 		(void) slc90e66_tune_chipset(drive, speed);
 		return ((int) ide_dma_off_quietly);
 	}
 #endif
-	if ((id->dma_ultra & 0x0010) && (ultra)) {
-		speed = (udma_66) ? XFER_UDMA_4 : XFER_UDMA_2;
-	} else if ((id->dma_ultra & 0x0008) && (ultra)) {
-		speed = (udma_66) ? XFER_UDMA_3 : XFER_UDMA_1;
-	} else if ((id->dma_ultra & 0x0004) && (ultra)) {
-		speed = XFER_UDMA_2;
-	} else if ((id->dma_ultra & 0x0002) && (ultra)) {
-		speed = XFER_UDMA_1;
-	} else if ((id->dma_ultra & 0x0001) && (ultra)) {
-		speed = XFER_UDMA_0;
-	} else if (id->dma_mword & 0x0004) {
-		speed = XFER_MW_DMA_2;
-	} else if (id->dma_mword & 0x0002) {
-		speed = XFER_MW_DMA_1;
-	} else if (id->dma_1word & 0x0004) {
-		speed = XFER_SW_DMA_2;
-        } else {
-		speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
-	}
+
+	speed = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA 
+					| (ultra ? XFER_UDMA : 0) | ((ultra && udma_66) ? XFER_UDMA_66 : 0));
 
 	(void) slc90e66_tune_chipset(drive, speed);
 
diff -urN linux-2.5.6/drivers/ide/umc8672.c linux-2.5.6-timing/drivers/ide/umc8672.c
--- linux-2.5.6/drivers/ide/umc8672.c	Wed Feb 20 03:10:59 2002
+++ linux-2.5.6-timing/drivers/ide/umc8672.c	Tue Mar 12 16:26:03 2002
@@ -52,7 +52,7 @@
 
 #include <asm/io.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
 /*
  * Default speeds.  These can be changed with "auto-tune" and/or hdparm.
@@ -113,7 +113,11 @@
 	unsigned long flags;
 	ide_hwgroup_t *hwgroup = ide_hwifs[HWIF(drive)->index^1].hwgroup;
 
-	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+	if (pio == 255)
+		pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
+	else
+		pio = min_t(byte, pio, 4);
+
 	printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", drive->name, pio, pio_to_umc[pio]);
 	save_flags(flags);	/* all CPUs */
 	cli();			/* all CPUs */
diff -urN linux-2.5.6/drivers/ide/via82cxxx.c linux-2.5.6-timing/drivers/ide/via82cxxx.c
--- linux-2.5.6/drivers/ide/via82cxxx.c	Tue Mar 12 16:05:40 2002
+++ linux-2.5.6-timing/drivers/ide/via82cxxx.c	Tue Mar 12 16:26:03 2002
@@ -352,7 +352,7 @@
 		return;
 	}
 
-	via_set_drive(drive, XFER_PIO_0 + MIN(pio, 5));
+	via_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5));
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 15:59             ` Vojtech Pavlik
@ 2002-03-12 16:11               ` Martin Dalecki
  2002-03-12 16:21                 ` Vojtech Pavlik
  2002-03-12 16:44                 ` Sebastian Droege
  2002-03-12 16:17               ` Martin Dalecki
  1 sibling, 2 replies; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 16:11 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML

Vojtech Pavlik wrote:
> On Tue, Mar 12, 2002 at 12:00:24PM +0100, Martin Dalecki wrote:
> 
> 
>>Hello Vojtech.
>>
>>I have noticed that the ide-timings.h and ide_modules.h are running
>>much in aprallel in the purpose they serve. Are the any
>>chances you could dare to care about propagating the
>>fairly nice ide-timings.h stuff in favour of
>>ide_modules.h more.
>>
>>BTW.> I think some stuff from ide-timings.h just belongs
>>as generic functions intro ide.c, and right now there is
>>nobody who you need to work from behind ;-).
>>
>>So please feel free to do the changes you apparently desired
>>to do a long time ago...
>>
> 
> Hmm, ok. Try this. It shouldn't change any functionality, yet makes a
> small step towards cleaning the chipset specific drivers.
> 
> Reading through them as I was doing the changes, I found out that most
> of them compute the timings incorrectly. Because of that I also removed
> the pio blacklist (which is going to come back in a more powerful form,
> merged together with the DMA blacklist), because that one is based on
> ancient experiments with the broken CMD640 chip and a driver which
> doesn't get the timings correct either. The blacklist is plain invalid.

Amen to this. May "the force" be with you! (I mean the force in you fingers!)

AS you may know I was once (an eon ago)
during the Marc Lord "era" involved in the initial developement of the cmd640
support. And well we got it working, but after that some friend got to the idea
of the black list and my disk went from georgious 5M/sec to only lame 2.8M/sec
rates (remember it was a conner 400MB drive then one of those "buggy" Quantums!)
for no good reason. I was long time patching every single kernel those time for
this. So if anything I very well know that the list found there is both:
obsolete and invalid. Further on my CMD640 code wasn't even trying to compute
the timing values in any dynamic ways. I was just using the original tables from
CMD directly, but unfortunately the maintainer enjoyed Z/ ring arithmetics too
much ;-)

> I plan to focus on the most important drivers first, to fix and clean
> them, working with the authors where possible.

PIIX na VIA comes to mind first ;-)...


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 15:59             ` Vojtech Pavlik
  2002-03-12 16:11               ` Martin Dalecki
@ 2002-03-12 16:17               ` Martin Dalecki
  2002-03-12 16:27                 ` Vojtech Pavlik
  1 sibling, 1 reply; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 16:17 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML

Vojtech Pavlik wrote:
> On Tue, Mar 12, 2002 at 12:00:24PM +0100, Martin Dalecki wrote:
> 
> 
>>Hello Vojtech.
>>
>>I have noticed that the ide-timings.h and ide_modules.h are running
>>much in aprallel in the purpose they serve. Are the any
>>chances you could dare to care about propagating the
>>fairly nice ide-timings.h stuff in favour of
>>ide_modules.h more.
>>
>>BTW.> I think some stuff from ide-timings.h just belongs
>>as generic functions intro ide.c, and right now there is
>>nobody who you need to work from behind ;-).
>>
>>So please feel free to do the changes you apparently desired
>>to do a long time ago...
>>
> 
> Hmm, ok. Try this. It shouldn't change any functionality, yet makes a
> small step towards cleaning the chipset specific drivers.


OK the patch looks fine. Taken. Still I have some notes:

1. Let's start calling stuff ATA and not IDE. (AT-Attachment is it
and not just Integrated Device Electornics.) OK?

2. I quite don't like the nested #include directives in ide-timing.h.
    It's cleaner to include the needed headers in front of usage
    of ide-timing.h. (Just s small note.... not really important...)

3. I wellcome that the MIN MAX macros there are gone. In fact
I have yerstoday just done basically the same ;-). (Will just have to
revert it now.

Patch swallowed.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:11               ` Martin Dalecki
@ 2002-03-12 16:21                 ` Vojtech Pavlik
  2002-03-12 16:26                   ` Martin Dalecki
  2002-03-13 19:43                   ` Bill Davidsen
  2002-03-12 16:44                 ` Sebastian Droege
  1 sibling, 2 replies; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-12 16:21 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: LKML

On Tue, Mar 12, 2002 at 05:11:13PM +0100, Martin Dalecki wrote:

> > Reading through them as I was doing the changes, I found out that most
> > of them compute the timings incorrectly. Because of that I also removed
> > the pio blacklist (which is going to come back in a more powerful form,
> > merged together with the DMA blacklist), because that one is based on
> > ancient experiments with the broken CMD640 chip and a driver which
> > doesn't get the timings correct either. The blacklist is plain invalid.
> 
> Amen to this. May "the force" be with you! (I mean the force in you fingers!)
> 
> AS you may know I was once (an eon ago)
> during the Marc Lord "era" involved in the initial developement of the cmd640
> support. And well we got it working, but after that some friend got to the idea
> of the black list and my disk went from georgious 5M/sec to only lame 2.8M/sec
> rates (remember it was a conner 400MB drive then one of those "buggy" Quantums!)
> for no good reason. I was long time patching every single kernel those time for
> this. So if anything I very well know that the list found there is both:
> obsolete and invalid. Further on my CMD640 code wasn't even trying to compute
> the timing values in any dynamic ways. I was just using the original tables from
> CMD directly, but unfortunately the maintainer enjoyed Z/ ring arithmetics too
> much ;-)

Well, as much as I'd like to use safe pre-computed register values for
the chips, that ain't possible - even when we assumed the system bus
(PCI, VLB, whatever) was always 33 MHz, still the drives have various
ideas about what DMA and PIO modes should look like, see the tDMA and
tPIO entries in hdparm -t.  

So, arithmetics has to stay. Hopefully just one instance in
ide-timing.c.

> > I plan to focus on the most important drivers first, to fix and clean
> > them, working with the authors where possible.
> 
> PIIX na VIA comes to mind first ;-)...

VIA is already OK, well, it has my name in it. :) AMD is now also (well,
that one wasn't broken, just ugly), SiS is being revamped by Lionel
Bouton (whom I'm trying to help as much as I can), so yes, PIIX would be
next.

PIIX and ICH are pretty crazy hardware from the design perspective, very
legacy-bound back to the first Intel PIIX chip. And the driver for these
in the kernel has similarly evolved following the hardware. However, it
doesn't seem to be wrong at the first glance. Nevertheless, I'll take a
look at it. Unfortunately, I don't have any Intel hardware at hand to
test it with.

-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:21                 ` Vojtech Pavlik
@ 2002-03-12 16:26                   ` Martin Dalecki
  2002-03-12 16:33                     ` Vojtech Pavlik
  2002-03-13 19:43                   ` Bill Davidsen
  1 sibling, 1 reply; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 16:26 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML

Vojtech Pavlik wrote:


> Well, as much as I'd like to use safe pre-computed register values for
> the chips, that ain't possible - even when we assumed the system bus
> (PCI, VLB, whatever) was always 33 MHz, still the drives have various
> ideas about what DMA and PIO modes should look like, see the tDMA and
> tPIO entries in hdparm -t.  

Yes yes yes of course some of the drivers are confused. And I don't
argue that precomputation is adequate right now. It just wasn't for
the CMD640 those times... I only wanted to reffer to history and
why my timings where different then the computed.

> So, arithmetics has to stay. Hopefully just one instance in
> ide-timing.c.
> 
> 
>>>I plan to focus on the most important drivers first, to fix and clean
>>>them, working with the authors where possible.
>>>
>>PIIX na VIA comes to mind first ;-)...
>>
> 
> VIA is already OK, well, it has my name in it. :) AMD is now also (well,

Oh of course I was reffering to VIA as important.

> that one wasn't broken, just ugly), SiS is being revamped by Lionel
> Bouton (whom I'm trying to help as much as I can), so yes, PIIX would be
> next.

I swallowed his SiS stuff already, since my home main machine is
a SiS735 based board. (Awfoul cheap that thing and quite good price/performance
ratio ;-).

> PIIX and ICH are pretty crazy hardware from the design perspective, very
> legacy-bound back to the first Intel PIIX chip. And the driver for these

Yes I "love" the bound together DMA areas as well ;-).

> in the kernel has similarly evolved following the hardware. However, it
> doesn't seem to be wrong at the first glance. Nevertheless, I'll take a
> look at it. Unfortunately, I don't have any Intel hardware at hand to
> test it with.

Just another hint: dmaproc is silly nomenclature is should be
dma_strategy <- this would better reflect it's purpose.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:17               ` Martin Dalecki
@ 2002-03-12 16:27                 ` Vojtech Pavlik
  2002-03-12 16:32                   ` Martin Dalecki
  0 siblings, 1 reply; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-12 16:27 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: LKML

On Tue, Mar 12, 2002 at 05:17:35PM +0100, Martin Dalecki wrote:
> Vojtech Pavlik wrote:
> > On Tue, Mar 12, 2002 at 12:00:24PM +0100, Martin Dalecki wrote:
> > 
> > 
> >>Hello Vojtech.
> >>
> >>I have noticed that the ide-timings.h and ide_modules.h are running
> >>much in aprallel in the purpose they serve. Are the any
> >>chances you could dare to care about propagating the
> >>fairly nice ide-timings.h stuff in favour of
> >>ide_modules.h more.
> >>
> >>BTW.> I think some stuff from ide-timings.h just belongs
> >>as generic functions intro ide.c, and right now there is
> >>nobody who you need to work from behind ;-).
> >>
> >>So please feel free to do the changes you apparently desired
> >>to do a long time ago...
> >>
> > 
> > Hmm, ok. Try this. It shouldn't change any functionality, yet makes a
> > small step towards cleaning the chipset specific drivers.
> 
> 
> OK the patch looks fine. Taken. Still I have some notes:
> 
> 1. Let's start calling stuff ATA and not IDE. (AT-Attachment is it
> and not just Integrated Device Electornics.) OK?

Sure. Feel free to rename whatever file/struct/variable you want. In my
opinion, it's just not worth caring about whether we call the stuff ATA
or IDE, both are TLAs with a long history. (Hmm, ATA probably means
Advanced Technology Attachment, right?)

But for new stuff, I'll try to stick with the 'ata' name.

> 2. I quite don't like the nested #include directives in ide-timing.h.
>     It's cleaner to include the needed headers in front of usage
>     of ide-timing.h. (Just s small note.... not really important...)

I can change that, or you can. I think the hdreg.h one is reasonable,
while the ide.h can probably go without any significant trouble. I think
the only file that'll need adding #include <ide.h> will be ide-timing.c

> 3. I wellcome that the MIN MAX macros there are gone. In fact
> I have yerstoday just done basically the same ;-). (Will just have to
> revert it now.
> 
> Patch swallowed.

-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:27                 ` Vojtech Pavlik
@ 2002-03-12 16:32                   ` Martin Dalecki
  0 siblings, 0 replies; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 16:32 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML

Vojtech Pavlik wrote:

>>OK the patch looks fine. Taken. Still I have some notes:
>>
>>1. Let's start calling stuff ATA and not IDE. (AT-Attachment is it
>>and not just Integrated Device Electornics.) OK?
>>
> 
> Sure. Feel free to rename whatever file/struct/variable you want. In my
> opinion, it's just not worth caring about whether we call the stuff ATA
> or IDE, both are TLAs with a long history. (Hmm, ATA probably means
> Advanced Technology Attachment, right?)

Basically I would like to try to follow the FreeBSD nomenclature as much as
possible, becouse:

1. I started doing Linux, becouse I like UNIX ;-).
2. It helps (in some distant time) to look at both side by side.
3. It helps to see what has changed "recently".
4. "Learning from the Soviet Union is learning about victory"... just kidding
I'm. But you are from .cz so you already know ;-).


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:26                   ` Martin Dalecki
@ 2002-03-12 16:33                     ` Vojtech Pavlik
  2002-03-12 16:41                       ` Martin Dalecki
  2002-03-12 16:43                       ` Martin Dalecki
  0 siblings, 2 replies; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-12 16:33 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: LKML

On Tue, Mar 12, 2002 at 05:26:20PM +0100, Martin Dalecki wrote:
> Vojtech Pavlik wrote:
> 
> 
> > Well, as much as I'd like to use safe pre-computed register values for
> > the chips, that ain't possible - even when we assumed the system bus
> > (PCI, VLB, whatever) was always 33 MHz, still the drives have various
> > ideas about what DMA and PIO modes should look like, see the tDMA and
> > tPIO entries in hdparm -t.  
> 
> Yes yes yes of course some of the drivers are confused. And I don't
> argue that precomputation is adequate right now. It just wasn't for
> the CMD640 those times... I only wanted to reffer to history and
> why my timings where different then the computed.

We may want to compare your original timings to what ide-timing.[ch]
will compute ...

> > So, arithmetics has to stay. Hopefully just one instance in
> > ide-timing.c.
> > 
> > 
> >>>I plan to focus on the most important drivers first, to fix and clean
> >>>them, working with the authors where possible.
> >>>
> >>PIIX na VIA comes to mind first ;-)...
> >>
> > 
> > VIA is already OK, well, it has my name in it. :) AMD is now also (well,
> 
> Oh of course I was reffering to VIA as important.
> 
> > that one wasn't broken, just ugly), SiS is being revamped by Lionel
> > Bouton (whom I'm trying to help as much as I can), so yes, PIIX would be
> > next.
> 
> I swallowed his SiS stuff already, since my home main machine is
> a SiS735 based board. (Awfoul cheap that thing and quite good price/performance
> ratio ;-).

As you can guess, I have mostly VIA machines around here. One SiS, too,
but that's an embedded board.

> > PIIX and ICH are pretty crazy hardware from the design perspective, very
> > legacy-bound back to the first Intel PIIX chip. And the driver for these
> 
> Yes I "love" the bound together DMA areas as well ;-).

And the SIDETIM register is just a kyooot idea. :)

> > in the kernel has similarly evolved following the hardware. However, it
> > doesn't seem to be wrong at the first glance. Nevertheless, I'll take a
> > look at it. Unfortunately, I don't have any Intel hardware at hand to
> > test it with.
> 
> Just another hint: dmaproc is silly nomenclature is should be
> dma_strategy <- this would better reflect it's purpose.

Dmaproc? Well that's a do-everything-possible-with-default-fallbacks
function. Quite an interesting approach, though I'd be much happier
without it.

Btw, do you know that the chipset and drives are tuned twice each boot?
First they're configured to PIO and half a second later to DMA (or PIO)
again ...

-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  0:51               ` Linus Torvalds
  2002-03-12  1:41                 ` Jeff Garzik
@ 2002-03-12 16:33                 ` Bill Davidsen
  1 sibling, 0 replies; 107+ messages in thread
From: Bill Davidsen @ 2002-03-12 16:33 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: LKML

On Mon, 11 Mar 2002, Linus Torvalds wrote:

> 
> 
> On Mon, 11 Mar 2002, Bill Davidsen wrote:
> >
> > I think you might want to offer an opinion (or edict, mandate, whatever)
> > WRT taskfile. While I think that some protective editing of commands is
> > desirable, useful, etc, I'm damn sure that some form of raw access is
> > required long term to allow diagmostics. I wouldn't argue if that
> > interface was required for low level format and other really drastic
> > operations as well.
> 
> Quite frankly, my personal opinion is that there's no point in trying to
> parse the commands too much at all. The _only_ thing the kernel should try
> to care about is that the buffers passed to the command are valid (ie the
> actual data in/out area pointer should be a kernel buffer as far as
> possible, not under user control).
> 
> Basically, there are three "modes" of operation here:
> 
>  - regular kernel access (ie the normal read/write stuff)
> 
>    parsing: none. The kernel originated the request.
> 
>  - common ioctl's that have nothing to do with IDE per se (ie all the
>    stuff to open/close/lock removable media, unlocking DVD's, reading
>    sound sectors etc - stuff that really exists elsewhere too, and where
>    the kernel should do the translation from the generic problem space to
>    the specific commands for the bus in quesion)
> 
>    Parsing: common ioctl turning stuff into common SCSI commands in the
>    "struct request".

This next part is the one I believe should be a compile/boot option, since
it is the one which provides full access to the device.
 
>  - totally IDE-only stuff, where the kernel simply doesn't add any value,
>    and only has a way of passing it down to the drive, and passing back
>    the requests.
> 
>    Parsing: none. The kernel simply doesn't have anything to do with the
>    request, except to synchronize it with all other requests.

	[observations on sync and queue issues understood and snipped]
-- 
bill davidsen <davidsen@tmr.com>
  CTO, TMR Associates, Inc
Doing interesting things with little computers since 1979.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  4:41                           ` Erik Andersen
  2002-03-12  4:48                             ` Jeff Garzik
  2002-03-12  6:29                             ` J. Dow
@ 2002-03-12 16:36                             ` Bill Davidsen
  2 siblings, 0 replies; 107+ messages in thread
From: Bill Davidsen @ 2002-03-12 16:36 UTC (permalink / raw)
  To: Erik Andersen; +Cc: LKML

On Mon, 11 Mar 2002, Erik Andersen wrote:

> On Mon Mar 11, 2002 at 10:10:36PM -0500, Jeff Garzik wrote:
> > 1) There should be a raw device command interface (not ATA or SCSI specific)
> 
> Hmm.  If such a generic low-level raw device layer were to be
> implemented (presumably as the foundation for the block layer), I
> expect the interface would be somthing like the cdrom layer, and
> would abstract out all the normal things that raw mass-storage
> devices can do.
> 
> But the minute such a layer is in place, people will begin going
> straight to the sub-low-level raw device layers so they can use
> all the exciting new extended features of their XP370000 quantum
> storage array which needs the special frob-electrons command to
> make it work...

Given that this has not happened with sg, nor with people using the
sg+ide-scsi, I think you would have to provide a good reason why this
would happen. The most likely path would be a separate driver or enhanced
IDE driver patch. User programs generally do read, write and seek, not
ioctl level hacking.

-- 
bill davidsen <davidsen@tmr.com>
  CTO, TMR Associates, Inc
Doing interesting things with little computers since 1979.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  0:34               ` Jeff Garzik
  2002-03-12  0:58                 ` Erik Andersen
@ 2002-03-12 16:40                 ` Bill Davidsen
  1 sibling, 0 replies; 107+ messages in thread
From: Bill Davidsen @ 2002-03-12 16:40 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: LKML

On Mon, 11 Mar 2002, Jeff Garzik wrote:

> And IMO, we should have some basic validation of taskfile requests in 
> the kernel...
> Reason 1: Standard kernel convention.  In other ioctls, we check basic 
> arguments and return EINVAL when they are wrong, even for privieleged 
> ioctls.

If we assume that this path is for commands the kernel doesn't understand,
how do we validate them?

> Reason 2: If you have multiple programs issuing ATA commands, you would 
> want a decent amount of synchronization, provided by the kernel, for the 
> multiple user processes and multiple kernel processes issuing requests. 
>  Having the userspace commands come down a single spot in the kernel 
> code makes this job a lot easier, if not making the impossible possible :)

Linus addressed this, I agree with his proposed three part implementation.
AFAIK he said the same thing in a different way.

-- 
bill davidsen <davidsen@tmr.com>
  CTO, TMR Associates, Inc
Doing interesting things with little computers since 1979.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:33                     ` Vojtech Pavlik
@ 2002-03-12 16:41                       ` Martin Dalecki
  2002-03-13  0:01                         ` Russell King
  2002-03-12 16:43                       ` Martin Dalecki
  1 sibling, 1 reply; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 16:41 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML

Vojtech Pavlik wrote:
> On Tue, Mar 12, 2002 at 05:26:20PM +0100, Martin Dalecki wrote:
> 
>>Vojtech Pavlik wrote:
>>
>>
>>
>>>Well, as much as I'd like to use safe pre-computed register values for
>>>the chips, that ain't possible - even when we assumed the system bus
>>>(PCI, VLB, whatever) was always 33 MHz, still the drives have various
>>>ideas about what DMA and PIO modes should look like, see the tDMA and
>>>tPIO entries in hdparm -t.  
>>>
>>Yes yes yes of course some of the drivers are confused. And I don't
>>argue that precomputation is adequate right now. It just wasn't for
>>the CMD640 those times... I only wanted to reffer to history and
>>why my timings where different then the computed.
>>
> 
> We may want to compare your original timings to what ide-timing.[ch]
> will compute ...
> 
> 
>>>So, arithmetics has to stay. Hopefully just one instance in
>>>ide-timing.c.
>>>
>>>
>>>
>>>>>I plan to focus on the most important drivers first, to fix and clean
>>>>>them, working with the authors where possible.
>>>>>
>>>>>
>>>>PIIX na VIA comes to mind first ;-)...
>>>>
>>>>
>>>VIA is already OK, well, it has my name in it. :) AMD is now also (well,
>>>
>>Oh of course I was reffering to VIA as important.
>>
>>
>>>that one wasn't broken, just ugly), SiS is being revamped by Lionel
>>>Bouton (whom I'm trying to help as much as I can), so yes, PIIX would be
>>>next.
>>>
>>I swallowed his SiS stuff already, since my home main machine is
>>a SiS735 based board. (Awfoul cheap that thing and quite good price/performance
>>ratio ;-).
>>
> 
> As you can guess, I have mostly VIA machines around here. One SiS, too,
> but that's an embedded board.
> 
> 
>>>PIIX and ICH are pretty crazy hardware from the design perspective, very
>>>legacy-bound back to the first Intel PIIX chip. And the driver for these
>>>
>>Yes I "love" the bound together DMA areas as well ;-).
>>
> 
> And the SIDETIM register is just a kyooot idea. :)
> 
> 
>>>in the kernel has similarly evolved following the hardware. However, it
>>>doesn't seem to be wrong at the first glance. Nevertheless, I'll take a
>>>look at it. Unfortunately, I don't have any Intel hardware at hand to
>>>test it with.
>>>
>>Just another hint: dmaproc is silly nomenclature is should be
>>dma_strategy <- this would better reflect it's purpose.
>>
> 
> Dmaproc? Well that's a do-everything-possible-with-default-fallbacks
> function. Quite an interesting approach, though I'd be much happier
> without it.

Yeep. As an added bonus it's error prone, if some implementation of this
method forgets to cut and paste the fallback code.
You noticed the way I made at least the file_operations dispatcher
looking "opaque" recently? Most visible was the vanishment of
dome

if (ban->bang == NULL)
     bang = default1
if (ban->bang == NULL)
     bang = default1
if (ban->bang == NULL)
     bang = default1
if (ban->bang == NULL)
     bang = default1
if (ban->bang == NULL)
     bang = default1
if (ban->bang == NULL)
     bang = default1
....

orgy upon "disk" initialization...

> Btw, do you know that the chipset and drives are tuned twice each boot?
> First they're configured to PIO and half a second later to DMA (or PIO)
> again ...

Yes I know ;-). I have just removed some other twice callers for
other stuff. Do you know for example that I'm about 90% sure that
cleanup hooks for the device category drivers can be called twice.
Or that adding just a single drive reiterates every one on the system?

First I will try to change the way disks get iterated. This is
becouse disks are the main object in the whole driver and not
the host chip channels... Look for the plenty loops with
MAX_HWIFS as upper bound to see what I mean.

"Tune" is a silly name as well BTW. It has nothing to do with
attaching of carbon fiber to cars. It's host chip initialization, which
is going on.



^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:33                     ` Vojtech Pavlik
  2002-03-12 16:41                       ` Martin Dalecki
@ 2002-03-12 16:43                       ` Martin Dalecki
  2002-03-12 16:50                         ` Vojtech Pavlik
  1 sibling, 1 reply; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 16:43 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML

Vojtech Pavlik wrote:
> On Tue, Mar 12, 2002 at 05:26:20PM +0100, Martin Dalecki wrote:
> 
>>Vojtech Pavlik wrote:
>>
>>
>>
>>>Well, as much as I'd like to use safe pre-computed register values for
>>>the chips, that ain't possible - even when we assumed the system bus
>>>(PCI, VLB, whatever) was always 33 MHz, still the drives have various
>>>ideas about what DMA and PIO modes should look like, see the tDMA and
>>>tPIO entries in hdparm -t.  
>>>
>>Yes yes yes of course some of the drivers are confused. And I don't
>>argue that precomputation is adequate right now. It just wasn't for
>>the CMD640 those times... I only wanted to reffer to history and
>>why my timings where different then the computed.
>>
> 
> We may want to compare your original timings to what ide-timing.[ch]
> will compute ...

Unfortunately there is no chance. I have abondony this board quite
happy a long time ago... It was an 486 and I don't keep old
shread around. Sorry I just don't have it at hand anylonger.



^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:11               ` Martin Dalecki
  2002-03-12 16:21                 ` Vojtech Pavlik
@ 2002-03-12 16:44                 ` Sebastian Droege
  1 sibling, 0 replies; 107+ messages in thread
From: Sebastian Droege @ 2002-03-12 16:44 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 918 bytes --]

Hi,

On Tue, 12 Mar 2002 17:21:34 +0100
Vojtech Pavlik <vojtech@suse.cz> wrote:

> VIA is already OK, well, it has my name in it. :) AMD is now also (well,
> that one wasn't broken, just ugly), SiS is being revamped by Lionel
> Bouton (whom I'm trying to help as much as I can), so yes, PIIX would be
> next.
> 
> PIIX and ICH are pretty crazy hardware from the design perspective, very
> legacy-bound back to the first Intel PIIX chip. And the driver for these
> in the kernel has similarly evolved following the hardware. However, it
> doesn't seem to be wrong at the first glance. Nevertheless, I'll take a
> look at it. Unfortunately, I don't have any Intel hardware at hand to
> test it with.

I have one Intel Corp. 82371AB PIIX4 IDE (rev 01) here and I can test it for you.
This machine isn't very important so it doesn't matter if some data gets shredded ;)
Just send me the patch when you've finished it.

Bye

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:43                       ` Martin Dalecki
@ 2002-03-12 16:50                         ` Vojtech Pavlik
  2002-03-12 16:58                           ` Martin Dalecki
  2002-03-14 14:02                           ` Pavel Machek
  0 siblings, 2 replies; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-12 16:50 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: LKML

On Tue, Mar 12, 2002 at 05:43:17PM +0100, Martin Dalecki wrote:
> Vojtech Pavlik wrote:
> > On Tue, Mar 12, 2002 at 05:26:20PM +0100, Martin Dalecki wrote:
> > 
> >>Vojtech Pavlik wrote:
> >>
> >>
> >>
> >>>Well, as much as I'd like to use safe pre-computed register values for
> >>>the chips, that ain't possible - even when we assumed the system bus
> >>>(PCI, VLB, whatever) was always 33 MHz, still the drives have various
> >>>ideas about what DMA and PIO modes should look like, see the tDMA and
> >>>tPIO entries in hdparm -t.  
> >>>
> >>Yes yes yes of course some of the drivers are confused. And I don't
> >>argue that precomputation is adequate right now. It just wasn't for
> >>the CMD640 those times... I only wanted to reffer to history and
> >>why my timings where different then the computed.
> >>
> > 
> > We may want to compare your original timings to what ide-timing.[ch]
> > will compute ...
> 
> Unfortunately there is no chance. I have abondony this board quite
> happy a long time ago... It was an 486 and I don't keep old
> shread around. Sorry I just don't have it at hand anylonger.

You may happen to have the numbers, though - that should be enough.

Btw, I have a CMD640B based PCI card lying around here, but never
managed to get it generate any interrupts, though the rest seems to be
working.

-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:50                         ` Vojtech Pavlik
@ 2002-03-12 16:58                           ` Martin Dalecki
  2002-03-14 14:02                           ` Pavel Machek
  1 sibling, 0 replies; 107+ messages in thread
From: Martin Dalecki @ 2002-03-12 16:58 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML

Vojtech Pavlik wrote:
> On Tue, Mar 12, 2002 at 05:43:17PM +0100, Martin Dalecki wrote:
> 
>>Vojtech Pavlik wrote:
>>
>>>On Tue, Mar 12, 2002 at 05:26:20PM +0100, Martin Dalecki wrote:
>>>
>>>
>>>>Vojtech Pavlik wrote:
>>>>
>>>>
>>>>
>>>>
>>>>>Well, as much as I'd like to use safe pre-computed register values for
>>>>>the chips, that ain't possible - even when we assumed the system bus
>>>>>(PCI, VLB, whatever) was always 33 MHz, still the drives have various
>>>>>ideas about what DMA and PIO modes should look like, see the tDMA and
>>>>>tPIO entries in hdparm -t.  
>>>>>
>>>>>
>>>>Yes yes yes of course some of the drivers are confused. And I don't
>>>>argue that precomputation is adequate right now. It just wasn't for
>>>>the CMD640 those times... I only wanted to reffer to history and
>>>>why my timings where different then the computed.
>>>>
>>>>
>>>We may want to compare your original timings to what ide-timing.[ch]
>>>will compute ...
>>>
>>Unfortunately there is no chance. I have abondony this board quite
>>happy a long time ago... It was an 486 and I don't keep old
>>shread around. Sorry I just don't have it at hand anylonger.
>>
> 
> You may happen to have the numbers, though - that should be enough.
> 
> Btw, I have a CMD640B based PCI card lying around here, but never
> managed to get it generate any interrupts, though the rest seems to be
> working.

I remember that I have found them in some readme attached to the
original dos drivers from CMD. Maybe it's still availabe on the net but
really I don't have it anylongeranywhere archieved. And BTW.> The CMD640B was
the variant which wasn't physically broken, as the CMD640 which had
improper bus termination of the secondary channel.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* [patch] PIIX driver rewrite
  2002-03-12 11:00           ` Martin Dalecki
  2002-03-12 15:59             ` Vojtech Pavlik
@ 2002-03-12 20:00             ` Vojtech Pavlik
  2002-03-12 20:35             ` Sebastian Droege
  2 siblings, 0 replies; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-12 20:00 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Sebastian Droege, LKML

[-- Attachment #1: Type: text/plain, Size: 1262 bytes --]

On Tue, Mar 12, 2002 at 12:00:24PM +0100, Martin Dalecki wrote:
> Hello Vojtech.
> 
> I have noticed that the ide-timings.h and ide_modules.h are running
> much in aprallel in the purpose they serve. Are the any
> chances you could dare to care about propagating the
> fairly nice ide-timings.h stuff in favour of
> ide_modules.h more.
> 
> BTW.> I think some stuff from ide-timings.h just belongs
> as generic functions intro ide.c, and right now there is
> nobody who you need to work from behind ;-).
> 
> So please feel free to do the changes you apparently desired
> to do a long time ago...

Oh, by the way, here goes the PIIX rewrite ... unlike the AMD one, this
is completely untested, and may not work at all - I only have the
datasheets at hand, no PIIX hardware.

Differences from the previous PIIX driver:

* 82451NX MIOC isn't supported anymore. It's not an ATA controller, anyway ;)
* 82371FB_0 PIIX ISA bridge isn't an ATA controller either.
* 82801CA ICH3 support added. Only ICH3-M is supported by the original driver.
* 82371MX MPIIX is not supported anymore. Too weird beast and doesn't do
  DMA anyway, better handled by the generic PCI ATA routines.

* Cleaner, converted to ide-timing.[ch]

* May not work. ;)

-- 
Vojtech Pavlik
SuSE Labs

[-- Attachment #2: ide-piix.diff --]
[-- Type: text/plain, Size: 35538 bytes --]

diff -urN linux-2.5.6-timing/drivers/ide/ide-pci.c linux-2.5.6-piix/drivers/ide/ide-pci.c
--- linux-2.5.6-timing/drivers/ide/ide-pci.c	Tue Mar 12 16:05:37 2002
+++ linux-2.5.6-piix/drivers/ide/ide-pci.c	Tue Mar 12 20:33:23 2002
@@ -119,6 +119,7 @@
 extern unsigned int pci_init_piix(struct pci_dev *);
 extern unsigned int ata66_piix(ide_hwif_t *);
 extern void ide_init_piix(ide_hwif_t *);
+extern void ide_dmacapable_piix(ide_hwif_t *, unsigned long);
 #endif
 
 #ifdef CONFIG_BLK_DEV_IT8172
@@ -197,19 +198,17 @@
 
 static ide_pci_device_t pci_chipsets[] __initdata = {
 #ifdef CONFIG_BLK_DEV_PIIX
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, NULL, NULL, ide_init_piix,	NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1, NULL, NULL, ide_init_piix,	NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX, NULL, NULL, ide_init_piix, NULL, {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}}, ON_BOARD, 0, ATA_F_NODMA },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, pci_init_piix, NULL, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, pci_init_piix, NULL,	ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1, pci_init_piix, NULL, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1, pci_init_piix, NULL, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1, pci_init_piix, ata66_piix, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1, pci_init_piix, ata66_piix, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_init_piix, NULL,	ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, ATA_F_NOADMA },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9, pci_init_piix, ata66_piix,	ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8, pci_init_piix, ata66_piix,	ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_init_piix, ata66_piix, ide_init_piix,	NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
 #endif
 #ifdef CONFIG_BLK_DEV_VIA82CXXX
 	{PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1,	pci_init_via82cxxx, ata66_via82cxxx, ide_init_via82cxxx, ide_dmacapable_via82cxxx, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0, ATA_F_NOADMA },
@@ -311,6 +310,7 @@
 	{PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, NULL, NULL, NULL, NULL, {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, ON_BOARD, 0, 0 },
 	{PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
 	{PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX, NULL, NULL, NULL, NULL, {{0x6D,0x80,0x80}, {0x00,0x00,0x00}}, ON_BOARD, 0, ATA_F_NODMA },
 	{PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, ATA_F_FIXIRQ },
 	{PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, ATA_F_FIXIRQ },
 	{PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, ATA_F_FIXIRQ },
diff -urN linux-2.5.6-timing/drivers/ide/piix.c linux-2.5.6-piix/drivers/ide/piix.c
--- linux-2.5.6-timing/drivers/ide/piix.c	Tue Mar 12 16:26:03 2002
+++ linux-2.5.6-piix/drivers/ide/piix.c	Tue Mar 12 20:35:40 2002
@@ -1,499 +1,510 @@
 /*
- *  linux/drivers/ide/piix.c		Version 0.32	June 9, 2000
+ * $Id: piix.c,v 1.1 2002/10/10 22:58:60 vojtech Exp $
  *
- *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
- *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
- *  May be copied or modified under the terms of the GNU General Public License
+ *  Copyright (c) 2000-2002 Vojtech Pavlik
  *
- *  PIO mode setting function for Intel chipsets.  
- *  For use instead of BIOS settings.
- *
- * 40-41
- * 42-43
- * 
- *                 41
- *                 43
- *
- * | PIO 0       | c0 | 80 | 0 | 	piix_tune_drive(drive, 0);
- * | PIO 2 | SW2 | d0 | 90 | 4 | 	piix_tune_drive(drive, 2);
- * | PIO 3 | MW1 | e1 | a1 | 9 | 	piix_tune_drive(drive, 3);
- * | PIO 4 | MW2 | e3 | a3 | b | 	piix_tune_drive(drive, 4);
- * 
- * sitre = word40 & 0x4000; primary
- * sitre = word42 & 0x4000; secondary
- *
- * 44 8421|8421    hdd|hdb
- * 
- * 48 8421         hdd|hdc|hdb|hda udma enabled
- *
- *    0001         hda
- *    0010         hdb
- *    0100         hdc
- *    1000         hdd
- *
- * 4a 84|21        hdb|hda
- * 4b 84|21        hdd|hdc
- *
- *    ata-33/82371AB
- *    ata-33/82371EB
- *    ata-33/82801AB            ata-66/82801AA
- *    00|00 udma 0              00|00 reserved
- *    01|01 udma 1              01|01 udma 3
- *    10|10 udma 2              10|10 udma 4
- *    11|11 reserved            11|11 reserved
- *
- * 54 8421|8421    ata66 drive|ata66 enable
- *
- * pci_read_config_word(HWIF(drive)->pci_dev, 0x40, &reg40);
- * pci_read_config_word(HWIF(drive)->pci_dev, 0x42, &reg42);
- * pci_read_config_word(HWIF(drive)->pci_dev, 0x44, &reg44);
- * pci_read_config_word(HWIF(drive)->pci_dev, 0x48, &reg48);
- * pci_read_config_word(HWIF(drive)->pci_dev, 0x4a, &reg4a);
- * pci_read_config_word(HWIF(drive)->pci_dev, 0x54, &reg54);
+ *  Based on the work of:
+ *	Andrzej Krzysztofowicz
+ *      Andre Hedrick
+ */
+
+/*
+ * Intel PIIX/ICH IDE driver for Linux.
  *
+ * UDMA66 and higher modes are autoenabled only in case the BIOS has detected a
+ * 80 wire cable. To ignore the BIOS data and assume the cable is present, use
+ * 'ide0=ata66' or 'ide1=ata66' on the kernel command line.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
 #include <linux/config.h>
-#include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
+#include <linux/blkdev.h>
 #include <linux/pci.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/delay.h>
 #include <linux/init.h>
-
+#include <linux/ide.h>
 #include <asm/io.h>
 
 #include "ide-timing.h"
 
-#define PIIX_DEBUG_DRIVE_INFO		0
+#define PIIX_IDETIM0		0x40
+#define PIIX_IDETIM1		0x42
+#define PIIX_SIDETIM		0x44
+#define PIIX_UDMACTL		0x48
+#define PIIX_UDMATIM		0x4a
+#define PIIX_IDECFG		0x54
+
+#define PIIX_UDMA		0x07
+#define PIIX_UDMA_33		0x01
+#define PIIX_UDMA_66		0x02
+#define PIIX_UDMA_100		0x03
+#define PIIX_NO_SITRE		0x08
+#define PIIX_PINGPONG		0x10
+#define PIIX_ISA		0x20
 
-#define DISPLAY_PIIX_TIMINGS
+/*
+ * Intel IDE chips
+ */
+
+static struct piix_ide_chip {
+	char *name;
+	unsigned short id;
+	unsigned char flags;
+} piix_ide_chips[] = {
+	{ "82801CA ICH3",		PCI_DEVICE_ID_INTEL_82801CA_11, PIIX_UDMA_100 | PIIX_PINGPONG },
+	{ "82801CAM ICH3-M",		PCI_DEVICE_ID_INTEL_82801CA_10, PIIX_UDMA_100 | PIIX_PINGPONG },
+	{ "82801BA ICH2",		PCI_DEVICE_ID_INTEL_82801BA_9,	PIIX_UDMA_100 | PIIX_PINGPONG },
+	{ "82801BAM ICH2-M",		PCI_DEVICE_ID_INTEL_82801BA_8,	PIIX_UDMA_100 | PIIX_PINGPONG },
+	{ "82801AB ICH0",		PCI_DEVICE_ID_INTEL_82801AB_1,	PIIX_UDMA_33  | PIIX_PINGPONG },
+	{ "82801AA ICH",		PCI_DEVICE_ID_INTEL_82801AA_1,	PIIX_UDMA_66  | PIIX_PINGPONG },
+	{ "82372FB PIIX5",		PCI_DEVICE_ID_INTEL_82372FB_1,	PIIX_UDMA_66 },	
+	{ "82443MX MPIIX4",		PCI_DEVICE_ID_INTEL_82443MX_1,	PIIX_UDMA_33 },
+	{ "82371AB/EB PIIX4/4E",	PCI_DEVICE_ID_INTEL_82371AB,	PIIX_UDMA_33 },
+	{ "82371SB PIIX3",		PCI_DEVICE_ID_INTEL_82371SB_1,	0 },
+	{ "82371FB PIIX",		PCI_DEVICE_ID_INTEL_82371FB_1,	PIIX_NO_SITRE },
+	{ NULL }
+};
+
+static struct piix_ide_chip *piix_config;
+static unsigned char piix_enabled;
+static unsigned int piix_80w;
+static unsigned int piix_clock;
+
+static char *piix_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100" };
+
+/*
+ * PIIX/ICH /proc entry.
+ */
+
+#ifdef CONFIG_PROC_FS
 
-#if defined(DISPLAY_PIIX_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
 
-static int piix_get_info(char *, char **, off_t, int);
-extern int (*piix_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+byte piix_proc;
+int piix_base;
 static struct pci_dev *bmide_dev;
+extern int (*piix_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+
+#define piix_print(format, arg...) p += sprintf(p, format "\n" , ## arg)
+#define piix_print_drive(name, format, arg...)\
+	p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n");
 
-static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
+static int piix_get_info(char *buffer, char **addr, off_t offset, int count)
 {
+	short speed[4], cycle[4], active[4], recover[4], dmaen[4], uen[4], udma[4], umul;
+	struct pci_dev *dev = bmide_dev;
+	unsigned int i, u;
+	unsigned short c, d, e;
+	unsigned char t;
 	char *p = buffer;
-	u32 bibma = pci_resource_start(bmide_dev, 4);
-        u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0;
-	u8  c0 = 0, c1 = 0;
-	u8  reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0, reg55 = 0;
-
-	if (bmide_dev->device == PCI_DEVICE_ID_INTEL_82371MX) {
-		p += sprintf(p, "\n                                Intel MPIIX Chipset.\n");
-		return p-buffer;	/* => must be less than 4k! */
-	}
-
-	pci_read_config_word(bmide_dev, 0x40, &reg40);
-	pci_read_config_word(bmide_dev, 0x42, &reg42);
-	pci_read_config_byte(bmide_dev, 0x44, &reg44);
-	pci_read_config_byte(bmide_dev, 0x48, &reg48);
-	pci_read_config_byte(bmide_dev, 0x4a, &reg4a);
-	pci_read_config_byte(bmide_dev, 0x4b, &reg4b);
-	pci_read_config_byte(bmide_dev, 0x54, &reg54);
-	pci_read_config_byte(bmide_dev, 0x55, &reg55);
-
-	psitre = (reg40 & 0x4000) ? 1 : 0;
-	ssitre = (reg42 & 0x4000) ? 1 : 0;
-
-	/*
-	 * at that point bibma+0x2 et bibma+0xa are byte registers
-	 * to investigate:
-	 */
-	c0 = inb_p((unsigned short)bibma + 0x02);
-	c1 = inb_p((unsigned short)bibma + 0x0a);
-
-	p += sprintf(p, "\n                    %s Chipset.\n", bmide_dev->name);
-	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
-	p += sprintf(p, "                %sabled                         %sabled\n",
-			(c0&0x80) ? "dis" : " en",
-			(c1&0x80) ? "dis" : " en");
-	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
-	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
-			(c0&0x20) ? "yes" : "no ",
-			(c0&0x40) ? "yes" : "no ",
-			(c1&0x20) ? "yes" : "no ",
-			(c1&0x40) ? "yes" : "no " );
-	p += sprintf(p, "UDMA enabled:   %s              %s             %s               %s\n",
-			(reg48&0x01) ? "yes" : "no ",
-			(reg48&0x02) ? "yes" : "no ",
-			(reg48&0x04) ? "yes" : "no ",
-			(reg48&0x08) ? "yes" : "no " );
-	p += sprintf(p, "UDMA enabled:   %s                %s               %s                 %s\n",
-			((reg54&0x11) && (reg55&0x10) && (reg4a&0x01)) ? "5" :
-			((reg54&0x11) && (reg4a&0x02)) ? "4" :
-			((reg54&0x11) && (reg4a&0x01)) ? "3" :
-			(reg4a&0x02) ? "2" :
-			(reg4a&0x01) ? "1" :
-			(reg4a&0x00) ? "0" : "X",
-			((reg54&0x22) && (reg55&0x20) && (reg4a&0x10)) ? "5" :
-			((reg54&0x22) && (reg4a&0x20)) ? "4" :
-			((reg54&0x22) && (reg4a&0x10)) ? "3" :
-			(reg4a&0x20) ? "2" :
-			(reg4a&0x10) ? "1" :
-			(reg4a&0x00) ? "0" : "X",
-			((reg54&0x44) && (reg55&0x40) && (reg4b&0x03)) ? "5" :
-			((reg54&0x44) && (reg4b&0x02)) ? "4" :
-			((reg54&0x44) && (reg4b&0x01)) ? "3" :
-			(reg4b&0x02) ? "2" :
-			(reg4b&0x01) ? "1" :
-			(reg4b&0x00) ? "0" : "X",
-			((reg54&0x88) && (reg55&0x80) && (reg4b&0x30)) ? "5" :
-			((reg54&0x88) && (reg4b&0x20)) ? "4" :
-			((reg54&0x88) && (reg4b&0x10)) ? "3" :
-			(reg4b&0x20) ? "2" :
-			(reg4b&0x10) ? "1" :
-			(reg4b&0x00) ? "0" : "X");
-
-	p += sprintf(p, "UDMA\n");
-	p += sprintf(p, "DMA\n");
-	p += sprintf(p, "PIO\n");
 
-/*
- *	FIXME.... Add configuration junk data....blah blah......
- */
+	piix_print("----------PIIX BusMastering IDE Configuration---------------");
+
+	piix_print("Driver Version:                     1.1");
+	piix_print("South Bridge:                       Intel %s", piix_config->name);
+
+	pci_read_config_byte(dev, PCI_REVISION_ID, &t);
+	piix_print("Revision:                           IDE %#x", t);
+
+	piix_print("BM-DMA base:                        %#x", piix_base);
+	piix_print("PCI clock:                          %dMHz", piix_clock);
+
+	piix_print("-----------------------Primary IDE-------Secondary IDE------");
+
+	pci_read_config_word(dev, PIIX_IDETIM0, &d);
+	pci_read_config_word(dev, PIIX_IDETIM1, &e);
+	piix_print("Enabled:               %10s%20s", (d & 0x8000) ? "yes" : "no", (e & 0x8000) ? "yes" : "no");
+
+	c = inb(piix_base + 0x02) | (inb(piix_base + 0x0a) << 8);
+	piix_print("Simplex only:          %10s%20s", (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no");
+
+	if ((piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66)
+		pci_read_config_dword(dev, PIIX_IDECFG, &u); else u = 0;
+	piix_print("Cable Type:            %10s%20s", (u & 0x30) ? "80w" : "40w", (u & 0xc0) ? "80w" : "40w");
+
+	piix_print("-------------------drive0----drive1----drive2----drive3-----");
+
+	piix_print_drive("Prefetch+Post: ", "%10s", (((i & 2) ? d : e) & (1 << (2 + ((i & 1) << 2)))) ? "yes" : "no");
+
+	if (~piix_config->flags & PIIX_NO_SITRE)
+		pci_read_config_byte(dev, PIIX_SIDETIM, &t);
+
+	for (i = 0; i < 4; i++) {
+
+		pci_read_config_word(dev, PIIX_IDETIM0 + (i & 2), &d);
+
+		umul = 4;
+		udma[i] = uen[i] = 0;
+		active[i] = 12;
+		recover[i] = 18;
 
-	return p-buffer;	 /* => must be less than 4k! */
+		switch (i & 1) {
+			case 1: if (~d & 0x10) break;
+				if ((~piix_config->flags & PIIX_NO_SITRE) && (d & 0x4000)) {
+					active[i]  = 5 - ((t >> ((i << 2) + 2)) & 3); 
+					recover[i] = 4 - ((t >> ((i << 2) + 0)) & 3); 
+					break;
+				}
+
+			case 0: if (~d & 0x01) break;
+				active[i] =  5 - ((d >> 12) & 3);
+				recover[i] = 4 - ((d >> 8) & 3);
+		}
+
+		dmaen[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
+
+		if (~piix_config->flags & PIIX_UDMA)
+			continue;
+
+		pci_read_config_byte(dev, PIIX_UDMACTL, &t);
+		pci_read_config_word(dev, PIIX_UDMATIM, &e);
+
+		if ((piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66 && (u & (1 << i))) umul = 2;
+		if ((piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100 && (u & ((1 << i) + 12))) umul = 1;
+
+		uen[i]  = (t & (1 << i)) ? dmaen[i] : 0;
+		udma[i] = (4 - ((e >> (i << 4)) & 3)) * umul;
+
+		speed[i] = 8 * piix_clock / (uen[i] ? udma[i] : (active[i] + recover[i]) * 4);
+		cycle[i] = 1000000 / piix_clock * (uen[i] ? udma[i] : (active[i] + recover[i]) * 4) / 4;
+	}
+
+	piix_print_drive("Transfer Mode: ", "%10s", dmaen[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
+
+	piix_print_drive("Address Setup: ", "%8dns", (1000000 / piix_clock) * 3);
+	piix_print_drive("Cmd Active:    ", "%8dns", (1000000 / piix_clock) * 12);
+	piix_print_drive("Cmd Recovery:  ", "%8dns", (1000000 / piix_clock) * 18);
+	piix_print_drive("Data Active:   ", "%8dns", (1000000 / piix_clock) * active[i]);
+	piix_print_drive("Data Recovery: ", "%8dns", (1000000 / piix_clock) * recover[i]);
+	piix_print_drive("Cycle Time:    ", "%8dns", cycle[i]);
+	piix_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10);
+
+	return p - buffer;	/* hoping it is less than 4K... */
 }
-#endif  /* defined(DISPLAY_PIIX_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+#endif
 
 /*
- *  Used to set Fifo configuration via kernel command line:
+ * piix_set_speed() writes timing values to the chipset registers
  */
 
-byte piix_proc = 0;
+static void piix_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timing *timing, int umul)
+{
+	unsigned short t;
+	unsigned char u;
+	unsigned int c;
+
+	pci_read_config_word(dev, PIIX_IDETIM0 + (dn & 2), &t);
+
+	switch (dn & 1) {
+
+		case 1: 
+			if (timing->cycle > 9) {
+				t &= ~0x30;
+				break;
+			}
 
-extern char *ide_xfer_verbose (byte xfer_rate);
+			if (~piix_config->flags & PIIX_NO_SITRE) {
+				pci_read_config_byte(dev, PIIX_SIDETIM, &u);
+				u &= ~(0xf << ((dn & 2) << 1));
+				t |= 0x30;
+				u |= (4 - FIT(timing->recover, 1, 4));
+				u |= (5 - FIT(timing->active, 2, 5)) << 2;
+				pci_write_config_byte(dev, PIIX_SIDETIM, u);
+				break;
+			}
 
-#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_PIIX_TUNING)
-/*
- *
- */
-static byte piix_dma_2_pio (byte xfer_rate) {
-	switch(xfer_rate) {
-		case XFER_UDMA_5:
-		case XFER_UDMA_4:
-		case XFER_UDMA_3:
-		case XFER_UDMA_2:
-		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;
+		case 0:
+			if (timing->cycle > 9) {
+				t &= ~0x03;
+				break;
+			}
+
+			t &= 0xccff;
+			t |= 0x03 << ((dn & 1) << 2);
+			t |= (4 - FIT(timing->recover, 1, 4)) << 8;
+			t |= (5 - FIT(timing->active, 2, 5)) << 12;
 	}
+
+	pci_write_config_word(dev, PIIX_IDETIM0 + (dn & 2), t);
+
+	if (!(piix_config->flags & PIIX_UDMA)) return;
+
+	pci_read_config_byte(dev, PIIX_UDMACTL, &u);
+	u &= ~(1 << dn);
+
+	if (timing->udma) {
+
+		u |= 1 << dn;
+
+		pci_read_config_word(dev, PIIX_UDMATIM, &t);
+		t &= ~(0x03 << (dn << 2));
+		t |= (4 - FIT(timing->udma, 2, 4)) << (dn << 2);
+		pci_write_config_word(dev, PIIX_UDMATIM, t);
+
+
+		if ((piix_config->flags & PIIX_UDMA) > PIIX_UDMA_33) {
+
+			pci_read_config_dword(dev, PIIX_IDECFG, &c);
+			
+			if ((piix_config->flags & PIIX_UDMA) > PIIX_UDMA_66)
+				c &= ~(1 << (dn + 12));
+			c &= ~(1 << dn);
+
+			switch (umul) {
+				case 2: c |= 1 << dn;		break;
+				case 4: c |= 1 << (dn + 12);	break;
+			}
+
+			pci_write_config_dword(dev, PIIX_IDECFG, c);
+		}
+	}
+
+	pci_write_config_byte(dev, PIIX_UDMACTL, u);
 }
-#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_PIIX_TUNING) */
 
 /*
- *  Based on settings done by AMI BIOS
- *  (might be useful if drive is not registered in CMOS for any reason).
+ * piix_set_drive() computes timing values configures the drive and
+ * the chipset to a desired transfer mode. It also can be called
+ * by upper layers.
  */
-static void piix_tune_drive (ide_drive_t *drive, byte pio)
-{
-	unsigned long flags;
-	u16 master_data;
-	u8 slave_data;
-	int is_slave		= (&HWIF(drive)->drives[1] == drive);
-	int master_port		= HWIF(drive)->index ? 0x42 : 0x40;
-	int slave_port		= 0x44;
-				 /* ISP  RTC */
-	byte timings[][2]	= { { 0, 0 },
-				    { 0, 0 },
-				    { 1, 0 },
-				    { 2, 1 },
-				    { 2, 3 }, };
-
-	if (pio == 255)
-		pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-	else
-		pio = min_t(byte, pio, 4);
-
-	pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
-	if (is_slave) {
-		master_data = master_data | 0x4000;
-		if (pio > 1)
-			/* enable PPE, IE and TIME */
-			master_data = master_data | 0x0070;
-		pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data);
-		slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0);
-		slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1])
-					   << (HWIF(drive)->index ? 4 : 0));
-	} else {
-		master_data = master_data & 0xccf8;
-		if (pio > 1)
-			/* enable PPE, IE and TIME */
-			master_data = master_data | 0x0007;
-		master_data = master_data | (timings[pio][0] << 12) |
-			      (timings[pio][1] << 8);
-	}
-	save_flags(flags);
-	cli();
-	pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data);
-	if (is_slave)
-		pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data);
-	restore_flags(flags);
-}
 
-#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_PIIX_TUNING)
-static int piix_tune_chipset (ide_drive_t *drive, byte speed)
+static int piix_set_drive(ide_drive_t *drive, unsigned char speed)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	byte maslave		= hwif->channel ? 0x42 : 0x40;
-	int a_speed		= 3 << (drive->dn * 4);
-	int u_flag		= 1 << drive->dn;
-	int v_flag		= 0x01 << drive->dn;
-	int w_flag		= 0x10 << drive->dn;
-	int u_speed		= 0;
-	int err			= 0;
-	int			sitre;
-	short			reg4042, reg44, reg48, reg4a, reg54;
-	byte			reg55;
-
-	pci_read_config_word(dev, maslave, &reg4042);
-	sitre = (reg4042 & 0x4000) ? 1 : 0;
-	pci_read_config_word(dev, 0x44, &reg44);
-	pci_read_config_word(dev, 0x48, &reg48);
-	pci_read_config_word(dev, 0x4a, &reg4a);
-	pci_read_config_word(dev, 0x54, &reg54);
-	pci_read_config_byte(dev, 0x55, &reg55);
-
-	switch(speed) {
-		case XFER_UDMA_4:
-		case XFER_UDMA_2:	u_speed = 2 << (drive->dn * 4); break;
-		case XFER_UDMA_5:
-		case XFER_UDMA_3:
-		case XFER_UDMA_1:	u_speed = 1 << (drive->dn * 4); break;
-		case XFER_UDMA_0:	u_speed = 0 << (drive->dn * 4); break;
-		case XFER_MW_DMA_2:
-		case XFER_MW_DMA_1:
-		case XFER_SW_DMA_2:	break;
-		default:		return -1;
-	}
-
-	if (speed >= XFER_UDMA_0) {
-		if (!(reg48 & u_flag))
-			pci_write_config_word(dev, 0x48, reg48|u_flag);
-		if (speed == XFER_UDMA_5) {
-			pci_write_config_byte(dev, 0x55, (byte) reg55|w_flag);
-		} else {
-			pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag);
-		}
-		if (!(reg4a & u_speed)) {
-			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
-			pci_write_config_word(dev, 0x4a, reg4a|u_speed);
-		}
-		if (speed > XFER_UDMA_2) {
-			if (!(reg54 & v_flag)) {
-				pci_write_config_word(dev, 0x54, reg54|v_flag);
-			}
-		} else {
-			pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
-		}
+	ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
+	struct ide_timing t, p;
+	int err, T, UT, umul;
+
+	if (speed != XFER_PIO_SLOW && speed != drive->current_speed)
+		if ((err = ide_config_drive_speed(drive, speed)))
+			return err;
+
+	umul =  min((speed > XFER_UDMA_4) ? 4 : ((speed > XFER_UDMA_2) ? 2 : 1),
+		piix_config->flags & PIIX_UDMA);
+
+	T = 1000000000 / piix_clock;
+	UT = T / umul;
+
+	ide_timing_compute(drive, speed, &t, T, UT);
+
+	if ((piix_config->flags & PIIX_NO_SITRE) && peer->present) {
+			ide_timing_compute(peer, peer->current_speed, &p, T, UT);
+			if (t.cycle <= 9 && p.cycle <= 9)
+				ide_timing_merge(&p, &t, &t, IDE_TIMING_ALL);
 	}
-	if (speed < XFER_UDMA_0) {
-		if (reg48 & u_flag)
-			pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
-		if (reg4a & a_speed)
-			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
-		if (reg54 & v_flag)
-			pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
-		if (reg55 & w_flag)
-			pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag);
-	}
-
-	piix_tune_drive(drive, piix_dma_2_pio(speed));
-
-#if PIIX_DEBUG_DRIVE_INFO
-	printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
-#endif /* PIIX_DEBUG_DRIVE_INFO */
-	if (!drive->init_speed)
+
+	piix_set_speed(HWIF(drive)->pci_dev, drive->dn, &t, umul);
+
+	if (!drive->init_speed)	
 		drive->init_speed = speed;
-	err = ide_config_drive_speed(drive, speed);
 	drive->current_speed = speed;
-	return err;
-}
 
-static int piix_config_drive_for_dma (ide_drive_t *drive)
-{
-	struct hd_driveid *id	= drive->id;
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	byte			speed;
-
-	byte udma_66		= eighty_ninty_three(drive);
-	int ultra100		= ((dev->device == PCI_DEVICE_ID_INTEL_82801BA_8) ||
-				   (dev->device == PCI_DEVICE_ID_INTEL_82801BA_9) ||
-				   (dev->device == PCI_DEVICE_ID_INTEL_82801CA_10)) ? 1 : 0;
-	int ultra66		= ((ultra100) ||
-				   (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) ||
-				   (dev->device == PCI_DEVICE_ID_INTEL_82372FB_1)) ? 1 : 0;
-	int ultra		= ((ultra66) ||
-				   (dev->device == PCI_DEVICE_ID_INTEL_82371AB) ||
-				   (dev->device == PCI_DEVICE_ID_INTEL_82443MX_1) ||
-				   (dev->device == PCI_DEVICE_ID_INTEL_82451NX) ||
-				   (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1)) ? 1 : 0;
-
-	speed = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA
-					| (ultra ? XFER_UDMA : 0) | ((udma_66 & ultra66) ? XFER_UDMA_66 : 0)
-					| ((udma_66 & ultra100) ? XFER_UDMA_100 : 0));
-
-	(void) piix_tune_chipset(drive, speed);
-
-	return ((int)	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-			((id->dma_1word >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+	return 0;
 }
 
-static void config_chipset_for_pio (ide_drive_t *drive)
-{
-	piix_tune_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0);
-}
+/*
+ * piix_tune_drive() is a callback from upper layers for
+ * PIO-only tuning.
+ */
 
-static int config_drive_xfer_rate (ide_drive_t *drive)
+static void piix_tune_drive(ide_drive_t *drive, unsigned char pio)
 {
-	struct hd_driveid *id = drive->id;
-	ide_dma_action_t dma_func = ide_dma_on;
+	if (!((piix_enabled >> HWIF(drive)->channel) & 1))
+		return;
 
-	if (id && (id->capability & 1) && HWIF(drive)->autodma) {
-		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
-			dma_func = ide_dma_off;
-			goto fast_ata_pio;
-		}
-		dma_func = ide_dma_off_quietly;
-		if (id->field_valid & 4) {
-			if (id->dma_ultra & 0x003F) {
-				/* Force if Capable UltraDMA */
-				dma_func = piix_config_drive_for_dma(drive);
-				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
-					goto try_dma_modes;
-			}
-		} else if (id->field_valid & 2) {
-try_dma_modes:
-			if ((id->dma_mword & 0x0007) ||
-			    (id->dma_1word & 0x007)) {
-				/* Force if Capable regular DMA modes */
-				dma_func = piix_config_drive_for_dma(drive);
-				if (dma_func != ide_dma_on)
-					goto no_dma_set;
-			}
-		} else if (ide_dmaproc(ide_dma_good_drive, drive)) {
-			if (id->eide_dma_time > 150) {
-				goto no_dma_set;
-			}
-			/* Consult the list of known "good" drives */
-			dma_func = piix_config_drive_for_dma(drive);
-			if (dma_func != ide_dma_on)
-				goto no_dma_set;
-		} else {
-			goto fast_ata_pio;
-		}
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
-no_dma_set:
-		config_chipset_for_pio(drive);
+	if (pio == 255) {
+		piix_set_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO));
+		return;
 	}
-	return HWIF(drive)->dmaproc(dma_func, drive);
+
+	piix_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5));
 }
 
-static int piix_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
+#ifdef CONFIG_BLK_DEV_IDEDMA
+
+/*
+ * piix_dmaproc() is a callback from upper layers that can do
+ * a lot, but we use it for DMA/PIO tuning only, delegating everything
+ * else to the default ide_dmaproc().
+ */
+
+int piix_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
 {
-	switch (func) {
-		case ide_dma_check:
-			return config_drive_xfer_rate(drive);
-		default :
-			break;
+
+	if (func == ide_dma_check) {
+
+		short w80 = HWIF(drive)->udma_four;
+
+		short speed = ide_find_best_mode(drive,
+			XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
+			(piix_config->flags & PIIX_UDMA ? XFER_UDMA : 0) |
+			(w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66 ? XFER_UDMA_66 : 0) |
+			(w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100 ? XFER_UDMA_100 : 0));
+
+		piix_set_drive(drive, speed);
+
+		func = (HWIF(drive)->autodma && (speed & XFER_MODE) != XFER_PIO)
+			? ide_dma_on : ide_dma_off_quietly;
+
 	}
-	/* Other cases are done by generic IDE-DMA code. */
+
 	return ide_dmaproc(func, drive);
 }
-#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_PIIX_TUNING) */
 
-unsigned int __init pci_init_piix(struct pci_dev *dev)
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+
+/*
+ * The initialization callback. Here we determine the IDE chip type
+ * and initialize its drive independent registers.
+ */
+
+unsigned int __init pci_init_piix(struct pci_dev *dev, const char *name)
 {
-#if defined(DISPLAY_PIIX_TIMINGS) && defined(CONFIG_PROC_FS)
+	unsigned int u;
+	unsigned short w;
+	int i;
+
+/*
+ * Find out which Intel IDE this is.
+ */
+	
+	for (piix_config = piix_ide_chips; piix_config->id; piix_config++)
+		if (dev->device == piix_config->id)
+			break;
+
+	if (!piix_config->id) {
+		printk(KERN_WARNING "PIIX: Unknown PIIX/ICH chip %#x, contact Vojtech Pavlik <vojtech@ucw.cz>\n", dev->device);
+		return -ENODEV;
+	}
+
+/*
+ * Check 80-wire cable presence.
+ */
+
+	if ((piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66) {
+		pci_read_config_dword(dev, PIIX_IDECFG, &u);
+		piix_80w = ((u & 0x30) ? 1 : 0) | ((u & 0xc0) ? 2 : 0);
+
+		if (piix_config->flags & PIIX_PINGPONG) {
+			u |= 0x400; 
+			pci_write_config_dword(dev, PIIX_IDECFG, u);
+		}
+	}
+
+/*
+ * Detect enabled interfaces, enable slave separate timing if possible.
+ */
+
+
+	for (i = 0; i < 2; i++) {
+		pci_read_config_word(dev, PIIX_IDETIM0 + (i << 1), &w);
+		piix_enabled |= (w & 0x8000) ? (1 << i) : 0;
+		w &= 0x8c00;
+		if (~piix_config->flags & PIIX_NO_SITRE) w |= 0x4000;
+		w |= 0x44;
+		pci_write_config_word(dev, PIIX_IDETIM0 + (i << 1), w);
+	}
+
+/*
+ * Determine the system bus clock.
+ */
+
+	piix_clock = system_bus_speed * 1000;
+
+	switch (piix_clock) {
+		case 33000: piix_clock = 33333; break;
+		case 37000: piix_clock = 37500; break;
+		case 41000: piix_clock = 41666; break;
+	}
+
+	if (piix_clock < 20000 || piix_clock > 50000) {
+		printk(KERN_WARNING "PIIX: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", piix_clock);
+		printk(KERN_WARNING "PIIX: Use ide0=ata66 if you want to assume 80-wire cable\n");
+		piix_clock = 33333;
+	}
+
+/*
+ * Print the boot message.
+ */
+
+	printk(KERN_INFO "PIIX: Intel %s IDE %s controller on pci%s\n",
+		piix_config->name, piix_dma[piix_config->flags & PIIX_UDMA], dev->slot_name);
+
+/*
+ * Register /proc/ide/piix entry
+ */
+
+#ifdef CONFIG_PROC_FS
 	if (!piix_proc) {
-		piix_proc = 1;
+		piix_base = pci_resource_start(dev, 4);
 		bmide_dev = dev;
 		piix_display_info = &piix_get_info;
+		piix_proc = 1;
 	}
-#endif /* DISPLAY_PIIX_TIMINGS && CONFIG_PROC_FS */
+#endif
+
 	return 0;
 }
 
-/*
- * Sheesh, someone at Intel needs to go read the ATA-4/5 T13 standards.
- * It does not specify device detection, but channel!!!
- * You determine later if bit 13 of word93 is set...
- */
-unsigned int __init ata66_piix (ide_hwif_t *hwif)
+unsigned int __init ata66_piix(ide_hwif_t *hwif)
 {
-	byte reg54h = 0, reg55h = 0, ata66 = 0;
-	byte mask = hwif->channel ? 0xc0 : 0x30;
-
-	pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h);
-	pci_read_config_byte(hwif->pci_dev, 0x55, &reg55h);
-
-	ata66 = (reg54h & mask) ? 1 : 0;
-
-	return ata66;
+	return ((piix_enabled & piix_80w) >> hwif->channel) & 1;
 }
 
-void __init ide_init_piix (ide_hwif_t *hwif)
+void __init ide_init_piix(ide_hwif_t *hwif)
 {
-#ifndef CONFIG_IA64
-	if (!hwif->irq)
-		hwif->irq = hwif->channel ? 15 : 14;
-#endif /* CONFIG_IA64 */
+	int i;
 
-	if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_82371MX) {
-		/* This is a painful system best to let it self tune for now */
-		return;
+	hwif->tuneproc = &piix_tune_drive;
+	hwif->speedproc = &piix_set_drive;
+	hwif->autodma = 0;
+
+	for (i = 0; i < 2; i++) {
+		hwif->drives[i].io_32bit = 1;
+		hwif->drives[i].unmask = 1;
+		hwif->drives[i].autotune = 1;
+		hwif->drives[i].dn = hwif->channel * 2 + i;
 	}
 
-	hwif->tuneproc = &piix_tune_drive;
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+#ifdef CONFIG_BLK_DEV_IDEDMA
+	if (hwif->dma_base) {
+		hwif->highmem = 1;
+		hwif->dmaproc = &piix_dmaproc;
+#ifdef CONFIG_IDEDMA_AUTO
+		if (!noautodma)
+			hwif->autodma = 1;
+#endif
+	}
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+}
 
-	if (!hwif->dma_base)
-		return;
+/*
+ * We allow the BM-DMA driver only work on enabled interfaces.
+ */
 
-	hwif->highmem = 1;
-#ifndef CONFIG_BLK_DEV_IDEDMA
-	hwif->autodma = 0;
-#else /* CONFIG_BLK_DEV_IDEDMA */
-#ifdef CONFIG_PIIX_TUNING
-	if (!noautodma)
-		hwif->autodma = 1;
-	hwif->dmaproc = &piix_dmaproc;
-	hwif->speedproc = &piix_tune_chipset;
-#endif /* CONFIG_PIIX_TUNING */
-#endif /* !CONFIG_BLK_DEV_IDEDMA */
+void __init ide_dmacapable_piix(ide_hwif_t *hwif, unsigned long dmabase)
+{
+	if ((piix_enabled >> hwif->channel) & 1)
+		ide_setup_dma(hwif, dmabase, 8);
 }

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  1:41                 ` Jeff Garzik
                                     ` (2 preceding siblings ...)
  2002-03-12 11:10                   ` [patch] My AMD IDE driver, v2.7 Martin Dalecki
@ 2002-03-12 20:21                   ` Gunther Mayer
  3 siblings, 0 replies; 107+ messages in thread
From: Gunther Mayer @ 2002-03-12 20:21 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: LKML

Jeff Garzik wrote:

> Linus, would it be acceptable to you to include an -optional- filter for
> ATA commands?  There is definitely a segment of users that would like to
> firewall their devices, and I think (as crazy as it may sound) that
> notion is a valid one.

A perfect filter exists already: it's called "non-root user" :-)



^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] PIIX driver rewrite
  2002-03-12 20:35             ` Sebastian Droege
@ 2002-03-12 20:34               ` Vojtech Pavlik
  2002-03-12 21:07               ` Sebastian Droege
  1 sibling, 0 replies; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-12 20:34 UTC (permalink / raw)
  To: Sebastian Droege; +Cc: Martin Dalecki, linux-kernel

On Tue, Mar 12, 2002 at 09:35:05PM +0100, Sebastian Droege wrote:
> On Tue, 12 Mar 2002 21:00:35 +0100
> Vojtech Pavlik <vojtech@suse.cz> wrote:
> 
> > On Tue, Mar 12, 2002 at 12:00:24PM +0100, Martin Dalecki wrote:
> > > Hello Vojtech.
> > > 
> > > I have noticed that the ide-timings.h and ide_modules.h are running
> > > much in aprallel in the purpose they serve. Are the any
> > > chances you could dare to care about propagating the
> > > fairly nice ide-timings.h stuff in favour of
> > > ide_modules.h more.
> > > 
> > > BTW.> I think some stuff from ide-timings.h just belongs
> > > as generic functions intro ide.c, and right now there is
> > > nobody who you need to work from behind ;-).
> > > 
> > > So please feel free to do the changes you apparently desired
> > > to do a long time ago...
> > 
> > Oh, by the way, here goes the PIIX rewrite ... unlike the AMD one, this
> > is completely untested, and may not work at all - I only have the
> > datasheets at hand, no PIIX hardware.
> > 
> > Differences from the previous PIIX driver:
> > 
> > * 82451NX MIOC isn't supported anymore. It's not an ATA controller, anyway ;)
> > * 82371FB_0 PIIX ISA bridge isn't an ATA controller either.
> > * 82801CA ICH3 support added. Only ICH3-M is supported by the original driver.
> > * 82371MX MPIIX is not supported anymore. Too weird beast and doesn't do
> >   DMA anyway, better handled by the generic PCI ATA routines.
> > 
> > * Cleaner, converted to ide-timing.[ch]
> > 
> > * May not work. ;)
> But does work with an Intel Corp. 82371AB PIIX4 IDE (rev 01) IDE controller...

Thanks a lot for the testing!

> I'll do some more stress testing but it boots, works in DMA and the data transfer rates haven't decreased ;)
> *playingwithhdparmanddbench* ;)

If you can (in addition to the benchmark numbers) also send me the
output of 'cat /proc/ide/piix' and 'dmesg' and 'lspci -vvxxx'both my and
the original version ... that'd help a lot too.

Thanks again,
-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] PIIX driver rewrite
  2002-03-12 11:00           ` Martin Dalecki
  2002-03-12 15:59             ` Vojtech Pavlik
  2002-03-12 20:00             ` [patch] PIIX driver rewrite Vojtech Pavlik
@ 2002-03-12 20:35             ` Sebastian Droege
  2002-03-12 20:34               ` Vojtech Pavlik
  2002-03-12 21:07               ` Sebastian Droege
  2 siblings, 2 replies; 107+ messages in thread
From: Sebastian Droege @ 2002-03-12 20:35 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1594 bytes --]

On Tue, 12 Mar 2002 21:00:35 +0100
Vojtech Pavlik <vojtech@suse.cz> wrote:

> On Tue, Mar 12, 2002 at 12:00:24PM +0100, Martin Dalecki wrote:
> > Hello Vojtech.
> > 
> > I have noticed that the ide-timings.h and ide_modules.h are running
> > much in aprallel in the purpose they serve. Are the any
> > chances you could dare to care about propagating the
> > fairly nice ide-timings.h stuff in favour of
> > ide_modules.h more.
> > 
> > BTW.> I think some stuff from ide-timings.h just belongs
> > as generic functions intro ide.c, and right now there is
> > nobody who you need to work from behind ;-).
> > 
> > So please feel free to do the changes you apparently desired
> > to do a long time ago...
> 
> Oh, by the way, here goes the PIIX rewrite ... unlike the AMD one, this
> is completely untested, and may not work at all - I only have the
> datasheets at hand, no PIIX hardware.
> 
> Differences from the previous PIIX driver:
> 
> * 82451NX MIOC isn't supported anymore. It's not an ATA controller, anyway ;)
> * 82371FB_0 PIIX ISA bridge isn't an ATA controller either.
> * 82801CA ICH3 support added. Only ICH3-M is supported by the original driver.
> * 82371MX MPIIX is not supported anymore. Too weird beast and doesn't do
>   DMA anyway, better handled by the generic PCI ATA routines.
> 
> * Cleaner, converted to ide-timing.[ch]
> 
> * May not work. ;)
But does work with an Intel Corp. 82371AB PIIX4 IDE (rev 01) IDE controller...
I'll do some more stress testing but it boots, works in DMA and the data transfer rates haven't decreased ;)
*playingwithhdparmanddbench* ;)

Bye

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] PIIX driver rewrite
  2002-03-12 20:35             ` Sebastian Droege
  2002-03-12 20:34               ` Vojtech Pavlik
@ 2002-03-12 21:07               ` Sebastian Droege
  2002-03-12 21:19                 ` Vojtech Pavlik
  1 sibling, 1 reply; 107+ messages in thread
From: Sebastian Droege @ 2002-03-12 21:07 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: martin, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 2688 bytes --]

On Tue, 12 Mar 2002 21:34:28 +0100
Vojtech Pavlik <vojtech@suse.cz> wrote:

> On Tue, Mar 12, 2002 at 09:35:05PM +0100, Sebastian Droege wrote:
> > On Tue, 12 Mar 2002 21:00:35 +0100
> > Vojtech Pavlik <vojtech@suse.cz> wrote:
> > 
> > > On Tue, Mar 12, 2002 at 12:00:24PM +0100, Martin Dalecki wrote:
> > > > Hello Vojtech.
> > > > 
> > > > I have noticed that the ide-timings.h and ide_modules.h are running
> > > > much in aprallel in the purpose they serve. Are the any
> > > > chances you could dare to care about propagating the
> > > > fairly nice ide-timings.h stuff in favour of
> > > > ide_modules.h more.
> > > > 
> > > > BTW.> I think some stuff from ide-timings.h just belongs
> > > > as generic functions intro ide.c, and right now there is
> > > > nobody who you need to work from behind ;-).
> > > > 
> > > > So please feel free to do the changes you apparently desired
> > > > to do a long time ago...
> > > 
> > > Oh, by the way, here goes the PIIX rewrite ... unlike the AMD one, this
> > > is completely untested, and may not work at all - I only have the
> > > datasheets at hand, no PIIX hardware.
> > > 
> > > Differences from the previous PIIX driver:
> > > 
> > > * 82451NX MIOC isn't supported anymore. It's not an ATA controller, anyway ;)
> > > * 82371FB_0 PIIX ISA bridge isn't an ATA controller either.
> > > * 82801CA ICH3 support added. Only ICH3-M is supported by the original driver.
> > > * 82371MX MPIIX is not supported anymore. Too weird beast and doesn't do
> > >   DMA anyway, better handled by the generic PCI ATA routines.
> > > 
> > > * Cleaner, converted to ide-timing.[ch]
> > > 
> > > * May not work. ;)
> > But does work with an Intel Corp. 82371AB PIIX4 IDE (rev 01) IDE controller...
> 
> Thanks a lot for the testing!
> 
> > I'll do some more stress testing but it boots, works in DMA and the data transfer rates haven't decreased ;)
> > *playingwithhdparmanddbench* ;)
> 
> If you can (in addition to the benchmark numbers) also send me the
> output of 'cat /proc/ide/piix' and 'dmesg' and 'lspci -vvxxx'both my and
> the original version ... that'd help a lot too.
OK here they are ;)
The only thing which confuses me is the line
PCI clock:                          33333MHz
in /proc/ide/piix
It should be 33 MHz I think
I think the mistake is in line 199 of piix.c:
piix_print("PCI clock:                          %dMHz", piix_clock);
has to be
piix_print("PCI clock:                          %dMHz", piix_clock / 1000);

or
the whole piix_clock stuff after line 432 is wrong

BTW: in /proc/ide/piix are sometimes wrong values for transfer rate and cycle time... I think they can't get negative ;)

Benchmark results come tomorrow

Bye

[-- Attachment #1.2: dmesg-new --]
[-- Type: application/octet-stream, Size: 9643 bytes --]

Linux version 2.5.6 (root@slomosnail) (gcc version 2.95.3 20010315 (release)) #5 Die Mär 12 21:20:36 CET 2002
BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 00000000000a0000 (usable)
 BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 000000000fff0000 (usable)
 BIOS-e820: 000000000fff0000 - 000000000fff3000 (ACPI NVS)
 BIOS-e820: 000000000fff3000 - 0000000010000000 (ACPI data)
 BIOS-e820: 00000000ffff0000 - 0000000100000000 (reserved)
255MB LOWMEM available.
ACPI: have wakeup address 0xc0001000
On node 0 totalpages: 65520
zone(0): 4096 pages.
zone(1): 61424 pages.
zone(2): 0 pages.
ACPI: RSDP (v000 MSISYS                     ) @ 0x000f6900
ACPI: RSDT (v001 MSISYS MS-6151W 12336.11825) @ 0x0fff3000
ACPI: FADT (v001 MSISYS MS-6151W 12336.11825) @ 0x0fff3040
Kernel command line: BOOT_IMAGE=2.5.6-2 rw root=341 hdc=scsi hdd=scsi
ide_setup: hdc=scsi
ide_setup: hdd=scsi
Local APIC disabled by BIOS -- reenabling.
Found and enabled local APIC!
Initializing CPU#0
Detected 350.804 MHz processor.
Console: colour VGA+ 80x25
Calibrating delay loop... 699.59 BogoMIPS
Memory: 256092k/262080k available (1780k kernel code, 5604k reserved, 529k data, 224k init, 0k highmem)
Dentry-cache hash table entries: 32768 (order: 6, 262144 bytes)
Inode-cache hash table entries: 16384 (order: 5, 131072 bytes)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer-cache hash table entries: 16384 (order: 4, 65536 bytes)
Page-cache hash table entries: 65536 (order: 6, 262144 bytes)
CPU: Before vendor init, caps: 0183fbff 00000000 00000000, vendor = 0
CPU: L1 I cache: 16K, L1 D cache: 16K
CPU: L2 cache: 512K
CPU: After vendor init, caps: 0183fbff 00000000 00000000 00000000
Intel machine check architecture supported.
Intel machine check reporting enabled on CPU#0.
CPU:     After generic, caps: 0183fbff 00000000 00000000 00000000
CPU:             Common caps: 0183fbff 00000000 00000000 00000000
CPU: Intel Pentium II (Deschutes) stepping 02
Enabling fast FPU save and restore... done.
Checking 'hlt' instruction... OK.
POSIX conformance testing by UNIFIX
enabled ExtINT on CPU#0
ESR value before enabling vector: 00000000
ESR value after enabling vector: 00000000
Using local APIC timer interrupts.
calibrating APIC timer ...
..... CPU clock speed is 350.8223 MHz.
..... host bus clock speed is 100.2347 MHz.
cpu: 0, clocks: 1002347, slice: 501173
CPU0<T0:1002336,T1:501152,D:11,S:501173,C:1002347>
mtrr: v1.40 (20010327) Richard Gooch (rgooch@atnf.csiro.au)
mtrr: detected mtrr type: Intel
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
ACPI: Bus Driver revision 20020308
ACPI: Core Subsystem revision 20020308
PCI: Using configuration type 1
ACPI: Interpreter enabled
ACPI: System [root] (supports S0 S1 S4 S5)
ACPI: PCI Root Bridge [PCI0] (00:00)
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
      00:00:0E[A] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:0E[B] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:0E[C] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:0E[D] -> \_SB_.PCI0.ISA_.LNKD[0]
      00:00:10[A] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:10[B] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:10[C] -> \_SB_.PCI0.ISA_.LNKD[0]
      00:00:10[D] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:12[A] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:12[B] -> \_SB_.PCI0.ISA_.LNKD[0]
      00:00:12[C] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:12[D] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:14[A] -> \_SB_.PCI0.ISA_.LNKD[0]
      00:00:14[B] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:14[C] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:14[D] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:07[A] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:07[B] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:07[C] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:07[D] -> \_SB_.PCI0.ISA_.LNKD[0]
      00:00:01[A] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:01[B] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:01[C] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:01[D] -> \_SB_.PCI0.ISA_.LNKD[0]
ACPI: PCI Interrupt Link [LNKA] (IRQs 3 4 5 6 7 10 *11 12 14 15)
ACPI: PCI Interrupt Link [LNKB] (IRQs *3 4 5 6 7 10 11 12 14 15)
ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 5 6 7 10 11 *12 14 15)
ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 6 7 *10 11 12 14 15)
PCI: Probing PCI hardware
PCI: Using ACPI for IRQ routing
Limiting direct PCI/PCI transfers.
Starting kswapd
BIO: pool of 256 setup, 14Kb (56 bytes/bio)
biovec: init pool 0, 1 entries, 12 bytes
biovec: init pool 1, 4 entries, 48 bytes
biovec: init pool 2, 16 entries, 192 bytes
biovec: init pool 3, 64 entries, 768 bytes
biovec: init pool 4, 128 entries, 1536 bytes
biovec: init pool 5, 256 entries, 3072 bytes
devfs: v1.11 (20020129) Richard Gooch (rgooch@atnf.csiro.au)
devfs: boot_options: 0x1
Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
ACPI: Power Button [PWRF]
ACPI: Power Button [PWRB]
ACPI: Processor [CPU0] (supports C1 C2, 8 throttling states)
keyboard: Timeout - AT keyboard not present?(ed)
keyboard: Timeout - AT keyboard not present?(f4)
pty: 256 Unix98 ptys configured
Real Time Clock Driver v1.11
block: 256 slots per queue, batch=32
Linux agpgart interface v0.99 (c) Jeff Hartmann
agpgart: Maximum main memory to use for agp memory: 203M
agpgart: Detected Intel 440BX chipset
agpgart: AGP aperture is 64M @ 0xe8000000
[drm] AGP 0.99 on Intel 440BX @ 0xe8000000 64MB
[drm] Initialized radeon 1.1.1 20010405 on minor 0
Uniform Multi-Platform E-IDE driver ver.:7.0.0
ide: system bus speed 33MHz
Intel Corp. 82371AB PIIX4 IDE: IDE controller on PCI slot 00:07.1
Intel Corp. 82371AB PIIX4 IDE: chipset revision 1
Intel Corp. 82371AB PIIX4 IDE: not 100% native mode: will probe irqs later
PIIX: Intel 82371AB/EB PIIX4/4E IDE UDMA33 controller on pci00:07.1
    ide0: BM-DMA at 0xf000-0xf007, BIOS settings: hda:DMA, hdb:DMA
    ide1: BM-DMA at 0xf008-0xf00f, BIOS settings: hdc:DMA, hdd:DMA
hda: IBM-DTTA-351010, ATA DISK drive
hdb: WDC WD800BB-00BSA0, ATA DISK drive
hdc: CD-W512EB, ATAPI CD/DVD-ROM drive
hdd: CD-532E-B, ATAPI CD/DVD-ROM drive
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
ide1 at 0x170-0x177,0x376 on irq 15
blk: queue c03a7c6c, I/O limit 4095Mb (mask 0xffffffff)
hda: 19807200 sectors (10141 MB) w/466KiB Cache, CHS=19650/16/63, UDMA(33)
blk: queue c03a7e8c, I/O limit 4095Mb (mask 0xffffffff)
hdb: 156301488 sectors (80026 MB) w/2048KiB Cache, CHS=155061/16/63, UDMA(33)
Partition check:
 /dev/ide/host0/bus0/target0/lun0: [PTBL] [1232/255/63] p1 p2 p4
 /dev/ide/host0/bus0/target1/lun0: p1 p2
SCSI subsystem driver Revision: 1.00
scsi0 : SCSI host adapter emulation for IDE ATAPI devices
  Vendor: TEAC      Model: CD-W512EB         Rev: 2.0E
  Type:   CD-ROM                             ANSI SCSI revision: 02
  Vendor: TEAC      Model: CD-532E-B         Rev: 3.0B
  Type:   CD-ROM                             ANSI SCSI revision: 02
Attached scsi CD-ROM sr0 at scsi0, channel 0, id 0, lun 0
Attached scsi CD-ROM sr1 at scsi0, channel 0, id 1, lun 0
sr0: scsi3-mmc drive: 32x/32x writer cd/rw xa/form2 cdda tray
Uniform CD-ROM driver Revision: 3.12
sr1: scsi3-mmc drive: 32x/32x cd/rw xa/form2 cdda tray
Advanced Linux Sound Architecture Driver Version 0.9.0beta12 (Wed Mar 06 07:56:20 2002 UTC).
kmod: failed to exec /sbin/modprobe -s -k snd-card-0, errno = 2
PCI: Found IRQ 12 for device 00:12.0
devfs_register(midi): could not append to parent, err: -17
ALSA device list:
  #0: ESS ES1938 (Solo-1) rev 0, irq 12
dmfe: Davicom DM9xxx net driver, version 1.36.4 (2002-01-17)
PCI: Found IRQ 10 for device 00:14.0
eth0: Davicom DM9102 at pci00:14.0, 00:00:ab:a1:27:8c, irq 10.
usb.c: registered new driver usbfs
usb.c: registered new driver hub
uhci.c: USB Universal Host Controller Interface driver v1.1
PCI: Found IRQ 10 for device 00:07.2
uhci.c: USB UHCI at I/O 0xd000, IRQ 10
hcd.c: new USB bus registered, assigned bus number 1
hub.c: USB hub found at /
hub.c: 2 ports detected
usb.c: registered new driver hid
hid-core.c: v1.31:USB HID core driver
usb.c: registered new driver usblp
printer.c: v0.10:USB Printer Device Class driver
mice: PS/2 mouse device common for all mice
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP, IGMP
IP: routing cache hash table of 2048 buckets, 16Kbytes
TCP: Hash tables configured (established 16384 bind 16384)
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
found reiserfs format "3.6" with standard journal
Reiserfs journal params: device 03:41, size 8192, journal first block 18, max trans len 1024, max batch 900, max commit age 30, max trans age 30
reiserfs: checking transaction log (ide0(3,65)) for (ide0(3,65))
Using r5 hash to sort names
VFS: Mounted root (reiserfs filesystem).
Mounted devfs on /dev
Freeing unused kernel memory: 224k freed
hub.c: new USB device on bus 1 path /1, assigned address 2
hub.c: USB hub found at /1
hub.c: 5 ports detected
Adding Swap: 273096k swap-space (priority 1)
found reiserfs format "3.6" with standard journal
hub.c: new USB device on bus 1 path /1/1, assigned address 3
hid-core.c: ctrl urb status -32 received
input: USB HID v1.00 Mouse [Microsoft Microsoft IntelliMouse® Explorer] on usb1:1.1
hub.c: new USB device on bus 1 path /1/4, assigned address 4
Reiserfs journal params: device 03:42, size 8192, journal first block 18, max trans len 1024, max batch 900, max commit age 30, max trans age 30
reiserfs: checking transaction log (ide0(3,66)) for (ide0(3,66))
Using r5 hash to sort names
usb_control/bulk_msg: timeout
input: USB HID v1.00 Keyboard [046a:0001] on usb1:1.4
blk: queue c03a7c6c, I/O limit 4095Mb (mask 0xffffffff)
blk: queue c03a7e8c, I/O limit 4095Mb (mask 0xffffffff)
dmfe: Change Speed to 100Mhz full duplex

[-- Attachment #1.3: dmesg-old --]
[-- Type: application/octet-stream, Size: 9532 bytes --]

Linux version 2.5.6 (root@slomosnail) (gcc version 2.95.3 20010315 (release)) #2 Die Mär 12 17:27:54 CET 2002
BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 00000000000a0000 (usable)
 BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 000000000fff0000 (usable)
 BIOS-e820: 000000000fff0000 - 000000000fff3000 (ACPI NVS)
 BIOS-e820: 000000000fff3000 - 0000000010000000 (ACPI data)
 BIOS-e820: 00000000ffff0000 - 0000000100000000 (reserved)
255MB LOWMEM available.
ACPI: have wakeup address 0xc0001000
On node 0 totalpages: 65520
zone(0): 4096 pages.
zone(1): 61424 pages.
zone(2): 0 pages.
ACPI: RSDP (v000 MSISYS                     ) @ 0x000f6900
ACPI: RSDT (v001 MSISYS MS-6151W 12336.11825) @ 0x0fff3000
ACPI: FADT (v001 MSISYS MS-6151W 12336.11825) @ 0x0fff3040
Kernel command line: BOOT_IMAGE=2.5.6 rw root=341 hdc=scsi hdd=scsi
ide_setup: hdc=scsi
ide_setup: hdd=scsi
Local APIC disabled by BIOS -- reenabling.
Found and enabled local APIC!
Initializing CPU#0
Detected 350.800 MHz processor.
Console: colour VGA+ 80x25
Calibrating delay loop... 699.59 BogoMIPS
Memory: 256092k/262080k available (1778k kernel code, 5604k reserved, 529k data, 224k init, 0k highmem)
Dentry-cache hash table entries: 32768 (order: 6, 262144 bytes)
Inode-cache hash table entries: 16384 (order: 5, 131072 bytes)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer-cache hash table entries: 16384 (order: 4, 65536 bytes)
Page-cache hash table entries: 65536 (order: 6, 262144 bytes)
CPU: Before vendor init, caps: 0183fbff 00000000 00000000, vendor = 0
CPU: L1 I cache: 16K, L1 D cache: 16K
CPU: L2 cache: 512K
CPU: After vendor init, caps: 0183fbff 00000000 00000000 00000000
Intel machine check architecture supported.
Intel machine check reporting enabled on CPU#0.
CPU:     After generic, caps: 0183fbff 00000000 00000000 00000000
CPU:             Common caps: 0183fbff 00000000 00000000 00000000
CPU: Intel Pentium II (Deschutes) stepping 02
Enabling fast FPU save and restore... done.
Checking 'hlt' instruction... OK.
POSIX conformance testing by UNIFIX
enabled ExtINT on CPU#0
ESR value before enabling vector: 00000000
ESR value after enabling vector: 00000000
Using local APIC timer interrupts.
calibrating APIC timer ...
..... CPU clock speed is 350.8087 MHz.
..... host bus clock speed is 100.2308 MHz.
cpu: 0, clocks: 1002308, slice: 501154
CPU0<T0:1002304,T1:501136,D:14,S:501154,C:1002308>
mtrr: v1.40 (20010327) Richard Gooch (rgooch@atnf.csiro.au)
mtrr: detected mtrr type: Intel
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
ACPI: Bus Driver revision 20020308
ACPI: Core Subsystem revision 20020308
PCI: Using configuration type 1
ACPI: Interpreter enabled
ACPI: System [root] (supports S0 S1 S4 S5)
ACPI: PCI Root Bridge [PCI0] (00:00)
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
      00:00:0E[A] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:0E[B] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:0E[C] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:0E[D] -> \_SB_.PCI0.ISA_.LNKD[0]
      00:00:10[A] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:10[B] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:10[C] -> \_SB_.PCI0.ISA_.LNKD[0]
      00:00:10[D] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:12[A] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:12[B] -> \_SB_.PCI0.ISA_.LNKD[0]
      00:00:12[C] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:12[D] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:14[A] -> \_SB_.PCI0.ISA_.LNKD[0]
      00:00:14[B] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:14[C] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:14[D] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:07[A] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:07[B] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:07[C] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:07[D] -> \_SB_.PCI0.ISA_.LNKD[0]
      00:00:01[A] -> \_SB_.PCI0.ISA_.LNKA[0]
      00:00:01[B] -> \_SB_.PCI0.ISA_.LNKB[0]
      00:00:01[C] -> \_SB_.PCI0.ISA_.LNKC[0]
      00:00:01[D] -> \_SB_.PCI0.ISA_.LNKD[0]
ACPI: PCI Interrupt Link [LNKA] (IRQs 3 4 5 6 7 10 *11 12 14 15)
ACPI: PCI Interrupt Link [LNKB] (IRQs *3 4 5 6 7 10 11 12 14 15)
ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 5 6 7 10 11 *12 14 15)
ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 6 7 *10 11 12 14 15)
PCI: Probing PCI hardware
PCI: Using ACPI for IRQ routing
Limiting direct PCI/PCI transfers.
Starting kswapd
BIO: pool of 256 setup, 14Kb (56 bytes/bio)
biovec: init pool 0, 1 entries, 12 bytes
biovec: init pool 1, 4 entries, 48 bytes
biovec: init pool 2, 16 entries, 192 bytes
biovec: init pool 3, 64 entries, 768 bytes
biovec: init pool 4, 128 entries, 1536 bytes
biovec: init pool 5, 256 entries, 3072 bytes
devfs: v1.11 (20020129) Richard Gooch (rgooch@atnf.csiro.au)
devfs: boot_options: 0x1
Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
ACPI: Power Button [PWRF]
ACPI: Power Button [PWRB]
ACPI: Processor [CPU0] (supports C1 C2, 8 throttling states)
keyboard: Timeout - AT keyboard not present?(ed)
keyboard: Timeout - AT keyboard not present?(f4)
pty: 256 Unix98 ptys configured
Real Time Clock Driver v1.11
block: 256 slots per queue, batch=32
Linux agpgart interface v0.99 (c) Jeff Hartmann
agpgart: Maximum main memory to use for agp memory: 203M
agpgart: Detected Intel 440BX chipset
agpgart: AGP aperture is 64M @ 0xe8000000
[drm] AGP 0.99 on Intel 440BX @ 0xe8000000 64MB
[drm] Initialized radeon 1.1.1 20010405 on minor 0
Uniform Multi-Platform E-IDE driver ver.:7.0.0
ide: system bus speed 33MHz
Intel Corp. 82371AB PIIX4 IDE: IDE controller on PCI slot 00:07.1
Intel Corp. 82371AB PIIX4 IDE: chipset revision 1
Intel Corp. 82371AB PIIX4 IDE: not 100% native mode: will probe irqs later
    ide0: BM-DMA at 0xf000-0xf007, BIOS settings: hda:DMA, hdb:DMA
    ide1: BM-DMA at 0xf008-0xf00f, BIOS settings: hdc:DMA, hdd:DMA
hda: IBM-DTTA-351010, ATA DISK drive
hdb: WDC WD800BB-00BSA0, ATA DISK drive
hdc: CD-W512EB, ATAPI CD/DVD-ROM drive
hdd: CD-532E-B, ATAPI CD/DVD-ROM drive
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
ide1 at 0x170-0x177,0x376 on irq 15
blk: queue c03a7c6c, I/O limit 4095Mb (mask 0xffffffff)
hda: 19807200 sectors (10141 MB) w/466KiB Cache, CHS=19650/16/63, UDMA(33)
blk: queue c03a7e8c, I/O limit 4095Mb (mask 0xffffffff)
hdb: 156301488 sectors (80026 MB) w/2048KiB Cache, CHS=155061/16/63, UDMA(33)
Partition check:
 /dev/ide/host0/bus0/target0/lun0: [PTBL] [1232/255/63] p1 p2 p4
 /dev/ide/host0/bus0/target1/lun0: p1 p2
SCSI subsystem driver Revision: 1.00
scsi0 : SCSI host adapter emulation for IDE ATAPI devices
  Vendor: TEAC      Model: CD-W512EB         Rev: 2.0E
  Type:   CD-ROM                             ANSI SCSI revision: 02
  Vendor: TEAC      Model: CD-532E-B         Rev: 3.0B
  Type:   CD-ROM                             ANSI SCSI revision: 02
Attached scsi CD-ROM sr0 at scsi0, channel 0, id 0, lun 0
Attached scsi CD-ROM sr1 at scsi0, channel 0, id 1, lun 0
sr0: scsi3-mmc drive: 32x/32x writer cd/rw xa/form2 cdda tray
Uniform CD-ROM driver Revision: 3.12
sr1: scsi3-mmc drive: 32x/32x cd/rw xa/form2 cdda tray
Advanced Linux Sound Architecture Driver Version 0.9.0beta12 (Wed Mar 06 07:56:20 2002 UTC).
kmod: failed to exec /sbin/modprobe -s -k snd-card-0, errno = 2
PCI: Found IRQ 12 for device 00:12.0
devfs_register(midi): could not append to parent, err: -17
ALSA device list:
  #0: ESS ES1938 (Solo-1) rev 0, irq 12
dmfe: Davicom DM9xxx net driver, version 1.36.4 (2002-01-17)
PCI: Found IRQ 10 for device 00:14.0
eth0: Davicom DM9102 at pci00:14.0, 00:00:ab:a1:27:8c, irq 10.
usb.c: registered new driver usbfs
usb.c: registered new driver hub
uhci.c: USB Universal Host Controller Interface driver v1.1
PCI: Found IRQ 10 for device 00:07.2
uhci.c: USB UHCI at I/O 0xd000, IRQ 10
hcd.c: new USB bus registered, assigned bus number 1
hub.c: USB hub found at /
hub.c: 2 ports detected
usb.c: registered new driver hid
hid-core.c: v1.31:USB HID core driver
usb.c: registered new driver usblp
printer.c: v0.10:USB Printer Device Class driver
mice: PS/2 mouse device common for all mice
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP, IGMP
IP: routing cache hash table of 2048 buckets, 16Kbytes
TCP: Hash tables configured (established 16384 bind 16384)
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
found reiserfs format "3.6" with standard journal
Reiserfs journal params: device 03:41, size 8192, journal first block 18, max trans len 1024, max batch 900, max commit age 30, max trans age 30
reiserfs: checking transaction log (ide0(3,65)) for (ide0(3,65))
Using r5 hash to sort names
VFS: Mounted root (reiserfs filesystem).
Mounted devfs on /dev
Freeing unused kernel memory: 224k freed
hub.c: new USB device on bus 1 path /1, assigned address 2
hub.c: USB hub found at /1
hub.c: 5 ports detected
Adding Swap: 273096k swap-space (priority 1)
found reiserfs format "3.6" with standard journal
hub.c: new USB device on bus 1 path /1/1, assigned address 3
hid-core.c: ctrl urb status -32 received
input: USB HID v1.00 Mouse [Microsoft Microsoft IntelliMouse® Explorer] on usb1:1.1
hub.c: new USB device on bus 1 path /1/4, assigned address 4
Reiserfs journal params: device 03:42, size 8192, journal first block 18, max trans len 1024, max batch 900, max commit age 30, max trans age 30
reiserfs: checking transaction log (ide0(3,66)) for (ide0(3,66))
usb_control/bulk_msg: timeout
input: USB HID v1.00 Keyboard [046a:0001] on usb1:1.4
Using r5 hash to sort names
blk: queue c03a7c6c, I/O limit 4095Mb (mask 0xffffffff)
blk: queue c03a7e8c, I/O limit 4095Mb (mask 0xffffffff)

[-- Attachment #1.4: lspci-new --]
[-- Type: application/octet-stream, Size: 13601 bytes --]

00:00.0 Host bridge: Intel Corp. 440BX/ZX - 82443BX/ZX Host bridge (rev 02)
	Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort+ >SERR- <PERR-
	Latency: 64
	Region 0: Memory at e8000000 (32-bit, prefetchable) [size=64M]
	Capabilities: [a0] AGP version 1.0
		Status: RQ=31 SBA+ 64bit- FW- Rate=x1,x2
		Command: RQ=0 SBA+ AGP+ 64bit- FW- Rate=x1
00: 86 80 90 71 06 00 10 22 02 00 00 06 00 40 00 00
10: 08 00 00 e8 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 a0 00 00 00 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 0c 8a 00 ff 00 00 00 09 03 10 11 03 00 00 00 00
60: 10 10 14 18 1c 20 20 20 00 33 40 a0 aa aa 00 00
70: 20 1f 0a 38 02 00 04 01 27 ff 10 38 00 00 00 00
80: 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 98 aa 00 00 04 61 00 00 00 05 00 00 00 00 00 00
a0: 02 00 10 00 03 02 00 1f 01 03 00 00 00 00 00 00
b0: 80 20 00 00 30 00 00 00 00 00 36 01 20 10 00 00
c0: 00 00 00 00 30 40 2a fb 18 0c ff ff 7f 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 4c ad ff bb 8a 3e 00 80 2c d3 f7 cf 9d 3e 00 00
f0: 40 01 00 00 00 f8 00 60 20 0f 00 00 00 00 00 00

00:01.0 PCI bridge: Intel Corp. 440BX/ZX - 82443BX/ZX AGP bridge (rev 02) (prog-if 00 [Normal decode])
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B-
	Status: Cap- 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64
	Bus: primary=00, secondary=01, subordinate=01, sec-latency=64
	I/O behind bridge: 0000c000-0000cfff
	Memory behind bridge: ec000000-edffffff
	Prefetchable memory behind bridge: e0000000-e7ffffff
	BridgeCtl: Parity- SERR- NoISA- VGA+ MAbort- >Reset- FastB2B+
00: 86 80 91 71 07 01 20 02 02 00 04 06 00 40 01 00
10: 00 00 00 00 00 00 00 00 00 01 01 40 c0 c0 a0 22
20: 00 ec f0 ed 00 e0 f0 e7 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00:07.0 ISA bridge: Intel Corp. 82371AB PIIX4 ISA (rev 02)
	Control: I/O+ Mem+ BusMaster+ SpecCycle+ MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 0
00: 86 80 10 71 0f 00 80 02 02 00 01 06 00 00 80 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 0b 03 0c 0a 10 00 00 00 00 f2 80 00 00 00 00 00
70: 00 00 00 00 00 00 0c 0c 00 00 00 00 00 00 00 00
80: 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 05 00 00 60 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 21 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00

00:07.1 IDE interface: Intel Corp. 82371AB PIIX4 IDE (rev 01) (prog-if 80 [Master])
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64
	Region 4: I/O ports at f000 [size=16]
00: 86 80 11 71 05 00 80 02 01 80 01 01 00 40 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 01 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 77 c0 77 c0 00 00 00 00 07 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00

00:07.2 USB Controller: Intel Corp. 82371AB PIIX4 USB (rev 01) (prog-if 00 [UHCI])
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64
	Interrupt: pin D routed to IRQ 10
	Region 4: I/O ports at d000 [size=32]
00: 86 80 12 71 05 00 80 02 01 00 03 0c 00 40 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 01 d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 0a 04 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00

00:07.3 Bridge: Intel Corp. 82371AB PIIX4 ACPI (rev 02)
	Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Interrupt: pin ? routed to IRQ 9
00: 86 80 13 71 03 00 80 02 02 00 80 06 00 00 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 01 40 00 00 00 00 00 00 00 30 00 01 00 00 00 00
50: 00 58 1f 00 00 00 00 00 07 0c 04 03 00 00 00 00
60: 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00
70: 04 40 11 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 01 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 09 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00

00:0e.0 VGA compatible controller: ATI Technologies Inc 3D Rage II+ 215GTB [Mach64 GTB] (rev 9a) (prog-if 00 [VGA])
	Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Region 0: Memory at ee000000 (32-bit, prefetchable) [disabled] [size=16M]
	Region 1: I/O ports at d400 [disabled] [size=256]
	Region 2: Memory at f1000000 (32-bit, non-prefetchable) [disabled] [size=4K]
	Expansion ROM at ef000000 [disabled] [size=128K]
00: 02 10 55 47 80 00 80 02 9a 00 00 03 08 40 00 00
10: 08 00 00 ee 01 d4 00 00 00 00 00 f1 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 ef 00 00 00 00 00 00 00 00 ff 00 08 00
40: 0c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00:12.0 Multimedia audio controller: ESS Technology ES1969 Solo-1 Audiodrive (rev 01)
	Subsystem: ESS Technology Solo-1 Audio Adapter
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64 (500ns min, 6000ns max)
	Interrupt: pin A routed to IRQ 12
	Region 0: I/O ports at d800 [size=64]
	Region 1: I/O ports at dc00 [size=16]
	Region 2: I/O ports at e000 [size=16]
	Region 3: I/O ports at e400 [size=4]
	Region 4: I/O ports at e800 [size=4]
	Capabilities: [c0] Power Management version 1
		Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
		Status: D0 PME-Enable- DSel=0 DScale=0 PME-
00: 5d 12 69 19 05 00 90 02 01 00 01 04 00 40 00 00
10: 01 d8 00 00 01 dc 00 00 01 e0 00 00 01 e4 00 00
20: 01 e8 00 00 00 00 00 00 00 00 00 00 5d 12 88 88
30: 00 00 00 00 c0 00 00 00 00 00 00 00 0c 01 02 18
40: 5f 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 01 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 01 00 21 06 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00:14.0 Ethernet controller: Davicom Semiconductor, Inc. Ethernet 100/10 MBit (rev 10)
	Subsystem: Davicom Semiconductor, Inc. Ethernet 100/10 MBit
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64 (5000ns min, 10000ns max)
	Interrupt: pin A routed to IRQ 10
	Region 0: I/O ports at ec00 [size=128]
	Region 1: Memory at f1020000 (32-bit, non-prefetchable) [size=128]
	Expansion ROM at f0000000 [disabled] [size=256K]
	Capabilities: [50] Power Management version 1
		Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot+,D3cold+)
		Status: D0 PME-Enable- DSel=0 DScale=0 PME-
00: 82 12 02 91 07 00 90 02 10 00 00 02 00 40 00 00
10: 01 ec 00 00 00 00 02 f1 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 82 12 02 91
30: 00 00 00 f0 50 00 00 00 00 00 00 00 0a 01 14 28
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 01 00 31 c0 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

01:00.0 VGA compatible controller: ATI Technologies Inc Radeon QD (prog-if 00 [VGA])
	Subsystem: ATI Technologies Inc: Unknown device 008a
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B-
	Status: Cap+ 66Mhz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64 (2000ns min), cache line size 08
	Interrupt: pin A routed to IRQ 11
	Region 0: Memory at e0000000 (32-bit, prefetchable) [size=128M]
	Region 1: I/O ports at c000 [size=256]
	Region 2: Memory at ed000000 (32-bit, non-prefetchable) [size=512K]
	Expansion ROM at <unassigned> [disabled] [size=128K]
	Capabilities: [58] AGP version 2.0
		Status: RQ=47 SBA+ 64bit- FW- Rate=x1,x2
		Command: RQ=31 SBA+ AGP+ 64bit- FW- Rate=x1
	Capabilities: [50] Power Management version 2
		Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
		Status: D0 PME-Enable- DSel=0 DScale=0 PME-
00: 02 10 44 51 87 00 b0 02 00 00 00 03 08 40 00 00
10: 08 00 00 e0 01 c0 00 00 00 00 00 ed 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 02 10 8a 00
30: 00 00 00 00 58 00 00 00 00 00 00 00 0b 01 08 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 02 10 8a 00
50: 01 00 02 06 00 00 00 00 02 50 20 00 03 02 00 2f
60: 01 03 00 1f 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


[-- Attachment #1.5: lspci-old --]
[-- Type: application/octet-stream, Size: 13601 bytes --]

00:00.0 Host bridge: Intel Corp. 440BX/ZX - 82443BX/ZX Host bridge (rev 02)
	Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort+ >SERR- <PERR-
	Latency: 64
	Region 0: Memory at e8000000 (32-bit, prefetchable) [size=64M]
	Capabilities: [a0] AGP version 1.0
		Status: RQ=31 SBA+ 64bit- FW- Rate=x1,x2
		Command: RQ=0 SBA+ AGP+ 64bit- FW- Rate=x1
00: 86 80 90 71 06 00 10 22 02 00 00 06 00 40 00 00
10: 08 00 00 e8 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 a0 00 00 00 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 0c 8a 00 ff 00 00 00 09 03 10 11 03 00 00 00 00
60: 10 10 14 18 1c 20 20 20 00 33 40 a0 aa aa 00 00
70: 20 1f 0a 38 02 00 04 01 27 ff 10 38 00 00 00 00
80: 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 98 aa 00 00 04 61 00 00 00 05 00 00 00 00 00 00
a0: 02 00 10 00 03 02 00 1f 01 03 00 00 00 00 00 00
b0: 80 20 00 00 30 00 00 00 00 00 36 01 20 10 00 00
c0: 00 00 00 00 30 40 2a fb 18 0c ff ff 7f 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 4c ad ff bb 8a 3e 00 80 2c d3 f7 cf 9d 3e 00 00
f0: 40 01 00 00 00 f8 00 60 20 0f 00 00 00 00 00 00

00:01.0 PCI bridge: Intel Corp. 440BX/ZX - 82443BX/ZX AGP bridge (rev 02) (prog-if 00 [Normal decode])
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B-
	Status: Cap- 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64
	Bus: primary=00, secondary=01, subordinate=01, sec-latency=64
	I/O behind bridge: 0000c000-0000cfff
	Memory behind bridge: ec000000-edffffff
	Prefetchable memory behind bridge: e0000000-e7ffffff
	BridgeCtl: Parity- SERR- NoISA- VGA+ MAbort- >Reset- FastB2B+
00: 86 80 91 71 07 01 20 02 02 00 04 06 00 40 01 00
10: 00 00 00 00 00 00 00 00 00 01 01 40 c0 c0 a0 22
20: 00 ec f0 ed 00 e0 f0 e7 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00:07.0 ISA bridge: Intel Corp. 82371AB PIIX4 ISA (rev 02)
	Control: I/O+ Mem+ BusMaster+ SpecCycle+ MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 0
00: 86 80 10 71 0f 00 80 02 02 00 01 06 00 00 80 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 0b 03 0c 0a 10 00 00 00 00 f2 80 00 00 00 00 00
70: 00 00 00 00 00 00 0c 0c 00 00 00 00 00 00 00 00
80: 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 05 00 00 60 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 21 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00

00:07.1 IDE interface: Intel Corp. 82371AB PIIX4 IDE (rev 01) (prog-if 80 [Master])
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64
	Region 4: I/O ports at f000 [size=16]
00: 86 80 11 71 05 00 80 02 01 80 01 01 00 40 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 01 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 77 e3 77 e3 bb 00 00 00 07 00 22 02 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00

00:07.2 USB Controller: Intel Corp. 82371AB PIIX4 USB (rev 01) (prog-if 00 [UHCI])
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64
	Interrupt: pin D routed to IRQ 10
	Region 4: I/O ports at d000 [size=32]
00: 86 80 12 71 05 00 80 02 01 00 03 0c 00 40 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 01 d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 0a 04 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00

00:07.3 Bridge: Intel Corp. 82371AB PIIX4 ACPI (rev 02)
	Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Interrupt: pin ? routed to IRQ 9
00: 86 80 13 71 03 00 80 02 02 00 80 06 00 00 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 01 40 00 00 00 00 00 00 00 30 00 01 00 00 00 00
50: 00 58 1f 00 00 00 00 00 07 0c 04 03 00 00 00 00
60: 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00
70: 04 40 11 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 01 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 09 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00

00:0e.0 VGA compatible controller: ATI Technologies Inc 3D Rage II+ 215GTB [Mach64 GTB] (rev 9a) (prog-if 00 [VGA])
	Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Region 0: Memory at ee000000 (32-bit, prefetchable) [disabled] [size=16M]
	Region 1: I/O ports at d400 [disabled] [size=256]
	Region 2: Memory at f1000000 (32-bit, non-prefetchable) [disabled] [size=4K]
	Expansion ROM at ef000000 [disabled] [size=128K]
00: 02 10 55 47 80 00 80 02 9a 00 00 03 08 40 00 00
10: 08 00 00 ee 01 d4 00 00 00 00 00 f1 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 ef 00 00 00 00 00 00 00 00 ff 00 08 00
40: 0c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00:12.0 Multimedia audio controller: ESS Technology ES1969 Solo-1 Audiodrive (rev 01)
	Subsystem: ESS Technology Solo-1 Audio Adapter
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64 (500ns min, 6000ns max)
	Interrupt: pin A routed to IRQ 12
	Region 0: I/O ports at d800 [size=64]
	Region 1: I/O ports at dc00 [size=16]
	Region 2: I/O ports at e000 [size=16]
	Region 3: I/O ports at e400 [size=4]
	Region 4: I/O ports at e800 [size=4]
	Capabilities: [c0] Power Management version 1
		Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
		Status: D0 PME-Enable- DSel=0 DScale=0 PME-
00: 5d 12 69 19 05 00 90 02 01 00 01 04 00 40 00 00
10: 01 d8 00 00 01 dc 00 00 01 e0 00 00 01 e4 00 00
20: 01 e8 00 00 00 00 00 00 00 00 00 00 5d 12 88 88
30: 00 00 00 00 c0 00 00 00 00 00 00 00 0c 01 02 18
40: 5f 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 01 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 01 00 21 06 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00:14.0 Ethernet controller: Davicom Semiconductor, Inc. Ethernet 100/10 MBit (rev 10)
	Subsystem: Davicom Semiconductor, Inc. Ethernet 100/10 MBit
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64 (5000ns min, 10000ns max)
	Interrupt: pin A routed to IRQ 10
	Region 0: I/O ports at ec00 [size=128]
	Region 1: Memory at f1020000 (32-bit, non-prefetchable) [size=128]
	Expansion ROM at f0000000 [disabled] [size=256K]
	Capabilities: [50] Power Management version 1
		Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot+,D3cold+)
		Status: D0 PME-Enable- DSel=0 DScale=0 PME-
00: 82 12 02 91 07 00 90 02 10 00 00 02 00 40 00 00
10: 01 ec 00 00 00 00 02 f1 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 82 12 02 91
30: 00 00 00 f0 50 00 00 00 00 00 00 00 0a 01 14 28
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 01 00 31 c0 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

01:00.0 VGA compatible controller: ATI Technologies Inc Radeon QD (prog-if 00 [VGA])
	Subsystem: ATI Technologies Inc: Unknown device 008a
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B-
	Status: Cap+ 66Mhz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 64 (2000ns min), cache line size 08
	Interrupt: pin A routed to IRQ 11
	Region 0: Memory at e0000000 (32-bit, prefetchable) [size=128M]
	Region 1: I/O ports at c000 [size=256]
	Region 2: Memory at ed000000 (32-bit, non-prefetchable) [size=512K]
	Expansion ROM at <unassigned> [disabled] [size=128K]
	Capabilities: [58] AGP version 2.0
		Status: RQ=47 SBA+ 64bit- FW- Rate=x1,x2
		Command: RQ=31 SBA+ AGP+ 64bit- FW- Rate=x1
	Capabilities: [50] Power Management version 2
		Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
		Status: D0 PME-Enable- DSel=0 DScale=0 PME-
00: 02 10 44 51 87 00 b0 02 00 00 00 03 08 40 00 00
10: 08 00 00 e0 01 c0 00 00 00 00 00 ed 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 02 10 8a 00
30: 00 00 00 00 58 00 00 00 00 00 00 00 0b 01 08 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 02 10 8a 00
50: 01 00 02 06 00 00 00 00 02 50 20 00 03 02 00 2f
60: 01 03 00 1f 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


[-- Attachment #1.6: piix-new --]
[-- Type: application/octet-stream, Size: 1083 bytes --]

----------PIIX BusMastering IDE Configuration---------------
Driver Version:                     1.1
South Bridge:                       Intel 82371AB/EB PIIX4/4E
Revision:                           IDE 0x1
BM-DMA base:                        0xf000
PCI clock:                          33333MHz
-----------------------Primary IDE-------Secondary IDE------
Enabled:                      yes                 yes
Simplex only:                  no                  no
Cable Type:                   40w                 40w
-------------------drive0----drive1----drive2----drive3-----
Prefetch+Post:        yes       yes       yes       yes
Transfer Mode:        DMA       DMA       DMA       DMA
Address Setup:       90ns      90ns      90ns      90ns
Cmd Active:         360ns     360ns     360ns     360ns
Cmd Recovery:       540ns     540ns     540ns     540ns
Data Active:        150ns     150ns     150ns     150ns
Data Recovery:      120ns     120ns     120ns     120ns
Cycle Time:         511ns       0ns     -22ns      -1ns
Transfer Rate:    0.0MB/s   0.0MB/s   4.0MB/s   0.0MB/s

[-- Attachment #1.7: piix-old --]
[-- Type: application/octet-stream, Size: 504 bytes --]


                    Intel Corp. 82371AB PIIX4 IDE Chipset.
--------------- Primary Channel ---------------- Secondary Channel -------------
                 enabled                          enabled
--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------
DMA enabled:    yes              yes             yes               yes
UDMA enabled:   yes              yes             yes               no 
UDMA enabled:   2                2               2                 X
UDMA
DMA
PIO

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] PIIX driver rewrite
  2002-03-12 21:07               ` Sebastian Droege
@ 2002-03-12 21:19                 ` Vojtech Pavlik
  0 siblings, 0 replies; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-12 21:19 UTC (permalink / raw)
  To: Sebastian Droege; +Cc: Vojtech Pavlik, martin, linux-kernel

Hi!

Thanks a lot, the /proc stuff indeed seems to be wrong. I'll fix that
tomorrow.

On Tue, Mar 12, 2002 at 10:07:01PM +0100, Sebastian Droege wrote:
> On Tue, 12 Mar 2002 21:34:28 +0100
> Vojtech Pavlik <vojtech@suse.cz> wrote:
> 
> > On Tue, Mar 12, 2002 at 09:35:05PM +0100, Sebastian Droege wrote:
> > > On Tue, 12 Mar 2002 21:00:35 +0100
> > > Vojtech Pavlik <vojtech@suse.cz> wrote:
> > > 
> > > > On Tue, Mar 12, 2002 at 12:00:24PM +0100, Martin Dalecki wrote:
> > > > > Hello Vojtech.
> > > > > 
> > > > > I have noticed that the ide-timings.h and ide_modules.h are running
> > > > > much in aprallel in the purpose they serve. Are the any
> > > > > chances you could dare to care about propagating the
> > > > > fairly nice ide-timings.h stuff in favour of
> > > > > ide_modules.h more.
> > > > > 
> > > > > BTW.> I think some stuff from ide-timings.h just belongs
> > > > > as generic functions intro ide.c, and right now there is
> > > > > nobody who you need to work from behind ;-).
> > > > > 
> > > > > So please feel free to do the changes you apparently desired
> > > > > to do a long time ago...
> > > > 
> > > > Oh, by the way, here goes the PIIX rewrite ... unlike the AMD one, this
> > > > is completely untested, and may not work at all - I only have the
> > > > datasheets at hand, no PIIX hardware.
> > > > 
> > > > Differences from the previous PIIX driver:
> > > > 
> > > > * 82451NX MIOC isn't supported anymore. It's not an ATA controller, anyway ;)
> > > > * 82371FB_0 PIIX ISA bridge isn't an ATA controller either.
> > > > * 82801CA ICH3 support added. Only ICH3-M is supported by the original driver.
> > > > * 82371MX MPIIX is not supported anymore. Too weird beast and doesn't do
> > > >   DMA anyway, better handled by the generic PCI ATA routines.
> > > > 
> > > > * Cleaner, converted to ide-timing.[ch]
> > > > 
> > > > * May not work. ;)
> > > But does work with an Intel Corp. 82371AB PIIX4 IDE (rev 01) IDE controller...
> > 
> > Thanks a lot for the testing!
> > 
> > > I'll do some more stress testing but it boots, works in DMA and the data transfer rates haven't decreased ;)
> > > *playingwithhdparmanddbench* ;)
> > 
> > If you can (in addition to the benchmark numbers) also send me the
> > output of 'cat /proc/ide/piix' and 'dmesg' and 'lspci -vvxxx'both my and
> > the original version ... that'd help a lot too.
> OK here they are ;)
> The only thing which confuses me is the line
> PCI clock:                          33333MHz
> in /proc/ide/piix
> It should be 33 MHz I think
> I think the mistake is in line 199 of piix.c:
> piix_print("PCI clock:                          %dMHz", piix_clock);
> has to be
> piix_print("PCI clock:                          %dMHz", piix_clock / 1000);
> 
> or
> the whole piix_clock stuff after line 432 is wrong
> 
> BTW: in /proc/ide/piix are sometimes wrong values for transfer rate and cycle time... I think they can't get negative ;)
> 
> Benchmark results come tomorrow
> 
> Bye









-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:41                       ` Martin Dalecki
@ 2002-03-13  0:01                         ` Russell King
  0 siblings, 0 replies; 107+ messages in thread
From: Russell King @ 2002-03-13  0:01 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Vojtech Pavlik, LKML

On Tue, Mar 12, 2002 at 05:41:29PM +0100, Martin Dalecki wrote:
> "Tune" is a silly name as well BTW. It has nothing to do with
> attaching of carbon fiber to cars. It's host chip initialization, which
> is going on.

Since when has carbon fiber got anything to do with Pianos and other
musical instruments that need to be "tuned" ?

tune vt.:

4. to adjust (an electronic circuit, a motor, etc.) to the proper or
   desired performance.

tune up:

2. to put (an engine) into good working order.

I therefore think "tune" (to tune the interface) is a reasonable name for
the function that is being performed.

-- 
Russell King (rmk@arm.linux.org.uk)                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html


^ permalink raw reply	[flat|nested] 107+ messages in thread

* ide filters / 'ide dump' / 'bio dump'
  2002-03-12  2:49                     ` Jeff Garzik
  2002-03-12 11:17                       ` Alan Cox
@ 2002-03-13  8:14                       ` bert hubert
  2002-03-13 10:11                         ` Jeff Garzik
  1 sibling, 1 reply; 107+ messages in thread
From: bert hubert @ 2002-03-13  8:14 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Alan Cox, Linus Torvalds, Bill Davidsen, LKML

On Tue, Mar 12, 2002 at 02:51:07AM +0000, Jeff Garzik wrote:

> The current implementation needs to be changed anyway :)  From "ATA raw 
> command" to "device raw command" at the very least.

Regarding proposed ATA filtering, this touches somewhat on something I've
been thinking about for a while: biodump.

Basically, biodump is to a block device what tcpdump is to a network
adaptor.

So we would be able to do this:

# biodump /dev/hda
09:09:33.023 READ block 12345 [10 blocks]
09:09:33.024 READ block 12355 [10 blocks]
09:09:33.025 READ block 12365 [10 blocks]
09:09:34.000 WRITE block 12345 [1 block]

Or somewhat more fancy, and only useful for non-growing files:

# biodump /var/db/bigdb/tablefile
file on /dev/hda, getting blockmap:
09:09:33.023 READ logical block 12345 [10 blocks]
09:09:33.024 READ logical block 12355 [10 blocks]
09:09:33.025 READ logical block 12365 [10 blocks]
09:09:34.000 WRITE logical block 12345 [1 block]

Because right now, we have no idea why that disk light is blinking. If
somebody implements a filter, it would be a natural place to also provide
a dumping hook.

biodump might in fact turn out to become atadump and scsidump (which is
rather sad actually).

regards,


bert

-- 
http://www.PowerDNS.com          Versatile DNS Software & Services
http://www.tk                              the dot in .tk
http://lartc.org           Linux Advanced Routing & Traffic Control HOWTO

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: ide filters / 'ide dump' / 'bio dump'
  2002-03-13  8:14                       ` ide filters / 'ide dump' / 'bio dump' bert hubert
@ 2002-03-13 10:11                         ` Jeff Garzik
  2002-03-13 12:05                           ` Malcolm Beattie
  2002-03-13 17:17                           ` Linus Torvalds
  0 siblings, 2 replies; 107+ messages in thread
From: Jeff Garzik @ 2002-03-13 10:11 UTC (permalink / raw)
  To: bert hubert; +Cc: Alan Cox, Linus Torvalds, Bill Davidsen, LKML

bert hubert wrote:

># biodump /dev/hda
>09:09:33.023 READ block 12345 [10 blocks]
>09:09:33.024 READ block 12355 [10 blocks]
>09:09:33.025 READ block 12365 [10 blocks]
>09:09:34.000 WRITE block 12345 [1 block]
>


Definitely an interesting idea...   With this new stuff Linus talked 
about in his proposal and what I'm thinking about, it shouldn't be too 
hard to do.

    Jeff





^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: ide filters / 'ide dump' / 'bio dump'
  2002-03-13 10:11                         ` Jeff Garzik
@ 2002-03-13 12:05                           ` Malcolm Beattie
  2002-03-13 17:17                           ` Linus Torvalds
  1 sibling, 0 replies; 107+ messages in thread
From: Malcolm Beattie @ 2002-03-13 12:05 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: bert hubert, Alan Cox, Linus Torvalds, Bill Davidsen, LKML

Jeff Garzik writes:
> bert hubert wrote:
> 
> ># biodump /dev/hda
> >09:09:33.023 READ block 12345 [10 blocks]
> >09:09:33.024 READ block 12355 [10 blocks]
> >09:09:33.025 READ block 12365 [10 blocks]
> >09:09:34.000 WRITE block 12345 [1 block]
> >
> 
> 
> Definitely an interesting idea...   With this new stuff Linus talked 
> about in his proposal and what I'm thinking about, it shouldn't be too 
> hard to do.

I wrote a basic version of that (reqlog) a couple of years ago (with
the writing of the rw/block/size info inline in the kernel rather than
via a nice separate filter). The use I put it to was for migrating
block devices live (i.e. while being read/written) without having to
quiesce the readers/writers except for a few seconds at the end. The
idea is that you set up (as an ordinary userland process) a bitmap
in memory for all the blocks on the device. You start with them all
marked dirty. You then do two loops concurrently (select() or threads):
    while (1) {
        read next block/size touched
        mark corresponding bits dirty in bitmap
    }
and
    while (1) {
        while (find_next_dirty_bit_in_bitmap()) {
		mark bit clean
		read corresponding block from device
		send blocknumber, blockdata to remote peer
	}
        go back to start of bitmap
    }

The remote peer is a daemon which just reads the (blocknumber,data)
pairs and writes the data to the snapshot-to-be device at its end.
Eventually, the bitmap gets mostly clean and the migrating process
has "caught up" and is just siphoning newly dirtied data off to the
remote end in real time. At that point, you quiesce the writing
applications nicely for a few seconds (database, serving daemons or
whatever is writing to the device) and let the migrator clean the
bitmap fully (the last few blocks) and at that point you have a
point-in-time safe snapshot at the remote end.

With filters available (presumably as modules) for the bio stuff,
this will become possible without having to patch the kernel (I think
I submitted the reqlog and bufflink patches for inclusion but
didn't care enough to keep trying).

See
    http://www.clueful.co.uk/mbeattie/linux-kernel.html#reqlog
and bmigrate and bufflink on the same page for the "old" way. It's
basic stuff and new APIs mean a rewrite will be much easier but I
thought you may be interested in another application of such logging.


--Malcolm
        
-- 
Malcolm Beattie <mbeattie@clueful.co.uk>
Linux Technical Consultant
IBM EMEA Enterprise Server Group...
...from home, speaking only for myself

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: ide filters / 'ide dump' / 'bio dump'
  2002-03-13 10:11                         ` Jeff Garzik
  2002-03-13 12:05                           ` Malcolm Beattie
@ 2002-03-13 17:17                           ` Linus Torvalds
  1 sibling, 0 replies; 107+ messages in thread
From: Linus Torvalds @ 2002-03-13 17:17 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: bert hubert, Alan Cox, Bill Davidsen, LKML



On Wed, 13 Mar 2002, Jeff Garzik wrote:
> bert hubert wrote:
>
> ># biodump /dev/hda
> >09:09:33.023 READ block 12345 [10 blocks]
> >09:09:33.024 READ block 12355 [10 blocks]
> >09:09:33.025 READ block 12365 [10 blocks]
> >09:09:34.000 WRITE block 12345 [1 block]
>
> Definitely an interesting idea...   With this new stuff Linus talked
> about in his proposal and what I'm thinking about, it shouldn't be too
> hard to do.

Note that I actually think we're talking about two different things.

There's the notion of _feeding_ special requests onto the request queue
through some interface that also can refuse to feed certain kinds of
requests. That is needed for the special commands, and is "above" the
requests queue layer.

That interface doesn't really support filtering of requests that other
people (notably the regular kernel itself) is also feeding to the request
queue.

Note that one of the big issues with the request queue is that it acts as
a funnel: it (very much by design) can, and does, take requests from
different places, and nobody needs to "own" the request queue. But the
kind of "feed this raw request down" module that has been talked about
would have absolutely _zero_ visibility into what others are feeding into
the request queue.

If you actually want to filter other peoples requests, then you have to do
something completely different, namely set up a request queue of your own,
then exporting _your_ request queue as the request queue for <major,minor>
and then taking the requests off that queue internally, and moving them to
the original queue after you've done filtering.

Basically a simplified "loopback" thing that doesn't even need to do any
remapping.

The two are totally independent, they work on requests queues at different
levels (one feeds some random request queue, the other changes how we look
up a request queue and inserts its own queue in between).

			Linus


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  1:50                       ` Jeff Garzik
  2002-03-11 18:50                         ` gmack
  2002-03-12  2:19                         ` Linus Torvalds
@ 2002-03-13 18:42                         ` Horst von Brand
  2002-03-13 19:11                           ` Andre Hedrick
  2 siblings, 1 reply; 107+ messages in thread
From: Horst von Brand @ 2002-03-13 18:42 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Bill Davidsen, LKML

Jeff Garzik <jgarzik@mandrakesoft.com>

[...]

> I -do- know the distrinction between hosts and devices.  I think there 
> should be -some- way, I don't care how, to filter out those unknown 
> commands (which may be perfectly valid for a small subset of special IBM 
> drives).  The net stack lets me do filtering, I want to sell you on the 
> idea of letting the ATA stack do the same thing.

The net stack does filtering for handling traffic from _untrusted_ external
sources, either for local consumtion or as a service for dumb machines
downstream, and as a way of limiting outward access to _untrusted_
users. Here we are talking of the ultimate _trusted_ user (root,
CAP_SYS_RAWIO, whatever). It makes no sense for the _kernel_ to get in the
way. Create a userland proggie for prodding IDE drives, and give it ways to
check (as far as terminal paranoia demands, a little, or not at all) as
desired. Unix ultimate simplicity is all about giving root enough rope to
shoot at his own feet.
-- 
Dr. Horst H. von Brand                   User #22616 counter.li.org
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-13 18:42                         ` Horst von Brand
@ 2002-03-13 19:11                           ` Andre Hedrick
  0 siblings, 0 replies; 107+ messages in thread
From: Andre Hedrick @ 2002-03-13 19:11 UTC (permalink / raw)
  To: Horst von Brand; +Cc: Jeff Garzik, Bill Davidsen, LKML

On Wed, 13 Mar 2002, Horst von Brand wrote:

> Jeff Garzik <jgarzik@mandrakesoft.com>
> 
> [...]
> 
> > I -do- know the distrinction between hosts and devices.  I think there 
> > should be -some- way, I don't care how, to filter out those unknown 
> > commands (which may be perfectly valid for a small subset of special IBM 
> > drives).  The net stack lets me do filtering, I want to sell you on the 
> > idea of letting the ATA stack do the same thing.
> 
> The net stack does filtering for handling traffic from _untrusted_ external
> sources, either for local consumtion or as a service for dumb machines
> downstream, and as a way of limiting outward access to _untrusted_
> users. Here we are talking of the ultimate _trusted_ user (root,
> CAP_SYS_RAWIO, whatever). It makes no sense for the _kernel_ to get in the
> way. Create a userland proggie for prodding IDE drives, and give it ways to
> check (as far as terminal paranoia demands, a little, or not at all) as
> desired. Unix ultimate simplicity is all about giving root enough rope to
> shoot at his own feet.


Greetings Dr. von Brand,

One of the issues that has been confused in the stack is the command
parser and/or sequencer.  It is used internally to allow quick and rapid
command additions as needed.  Most are not clear how the IOCTL works and
thinks it runs via the command parser, this is totally wrong.  The sad
part is the lenght of the rope does not hit the feet, it hits the head.

Regards,

Andre Hedrick


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:21                 ` Vojtech Pavlik
  2002-03-12 16:26                   ` Martin Dalecki
@ 2002-03-13 19:43                   ` Bill Davidsen
  1 sibling, 0 replies; 107+ messages in thread
From: Bill Davidsen @ 2002-03-13 19:43 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Martin Dalecki, LKML

On Tue, 12 Mar 2002, Vojtech Pavlik wrote:

> PIIX and ICH are pretty crazy hardware from the design perspective, very
> legacy-bound back to the first Intel PIIX chip. And the driver for these
> in the kernel has similarly evolved following the hardware. However, it
> doesn't seem to be wrong at the first glance. Nevertheless, I'll take a
> look at it. Unfortunately, I don't have any Intel hardware at hand to
> test it with.

I'm not sure "evolved" is the term you want, allow me to suggest
"mutated."

-- 
bill davidsen <davidsen@tmr.com>
  CTO, TMR Associates, Inc
Doing interesting things with little computers since 1979.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12 16:50                         ` Vojtech Pavlik
  2002-03-12 16:58                           ` Martin Dalecki
@ 2002-03-14 14:02                           ` Pavel Machek
  2002-03-15 11:13                             ` Vojtech Pavlik
  1 sibling, 1 reply; 107+ messages in thread
From: Pavel Machek @ 2002-03-14 14:02 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Martin Dalecki, LKML

Hi

> You may happen to have the numbers, though - that should be enough.
> 
> Btw, I have a CMD640B based PCI card lying around here, but never
> managed to get it generate any interrupts, though the rest seems to be
> working.

Attach it to the timer interrupt -- that should do it for testing. Simplest
way is to make ide timeouts HZ/100 and killing "lost interrupt" msg ;-).

								Pavel
-- 
Philips Velo 1: 1"x4"x8", 300gram, 60, 12MB, 40bogomips, linux, mutt,
details at http://atrey.karlin.mff.cuni.cz/~pavel/velo/index.html.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  4:13                             ` Jeff Garzik
@ 2002-03-14 14:13                               ` Pavel Machek
  2002-03-15 11:05                                 ` Jeff Garzik
  2002-03-15 14:45                                 ` Alan Cox
  0 siblings, 2 replies; 107+ messages in thread
From: Pavel Machek @ 2002-03-14 14:13 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Olivier Galibert, LKML

Hi

> Under more restricted domains, root cannot bit-bang the interface. 
>  s/CAP_SYS_RAWIO/CAP_DEVICE_CMD/ for the raw cmd ioctl interface.  Have 

Nobody uses capabilities these days, right?

> The filter is useful for other reasons like correctness, as well.

If you want to test if it works, you just disallow that access altogether.
It is usually not needed , anyway.
								Pavel
-- 
Philips Velo 1: 1"x4"x8", 300gram, 60, 12MB, 40bogomips, linux, mutt,
details at http://atrey.karlin.mff.cuni.cz/~pavel/velo/index.html.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-12  6:32                           ` Vojtech Pavlik
@ 2002-03-14 15:12                             ` Pavel Machek
  0 siblings, 0 replies; 107+ messages in thread
From: Pavel Machek @ 2002-03-14 15:12 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Linus Torvalds, Jeff Garzik, andersen, Bill Davidsen, LKML

Hi!

> Well, there are uses for the 'dynamic' filter, and it doesn't add too
> much complexity. One could be allowing certain commands to be performed
> on certain devices by normal users - eg. CD-burning or whatever without

That should be better done userspace: setuid on cdrecord + its security audit
seems like nice solution.

> root privileges (I know we're using ide-scsi for the command access
> right now ...), and also protecting the oneself from ACPI and the like.
> Because ACPI can do IDE commands and does that in a way interfaceable to
> a 'taskfile' kernel ioctl. It'd be nice to know a broken ACPI
> implementation can't screw up your drive easily through a kernel driver.

This is entirely different can of worms, and should be easy to do at ACPI
level.
									Pavel
-- 
Philips Velo 1: 1"x4"x8", 300gram, 60, 12MB, 40bogomips, linux, mutt,
details at http://atrey.karlin.mff.cuni.cz/~pavel/velo/index.html.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-14 14:13                               ` Pavel Machek
@ 2002-03-15 11:05                                 ` Jeff Garzik
  2002-03-18 19:20                                   ` Pavel Machek
  2002-03-15 14:45                                 ` Alan Cox
  1 sibling, 1 reply; 107+ messages in thread
From: Jeff Garzik @ 2002-03-15 11:05 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Olivier Galibert, LKML

Pavel Machek wrote:

>Hi
>
>>Under more restricted domains, root cannot bit-bang the interface. 
>> s/CAP_SYS_RAWIO/CAP_DEVICE_CMD/ for the raw cmd ioctl interface.  Have 
>>
>
>Nobody uses capabilities these days, right?
>

Actually, the NSA and HP secure linux products do, at the very least. 
 And there is some ELF capabilities project out there IIRC, but I dunno 
if anybody's using it.

>>The filter is useful for other reasons like correctness, as well.
>>
>
>If you want to test if it works, you just disallow that access altogether.
>It is usually not needed , anyway.
>

The filter, or directly sending drive commands to userspace?

I agree the filter is of limited usefulness.

Sending drive commands directly from userspace is definitely -very- 
useful.  As we start doing more and more stuff in userspace, I predict 
this facility will be used more and more.  Plus, IBM particularly 
already has their Drive Fitness Tests, or whatever, sending direct drive 
commands.  With the proper sequencing, you can even do power management 
of the drives in userspace.  You don't want to do system suspend/resume 
that way, but you can certainly have a userspace policy daemon running, 
that powers-down and powers-up the drives, etc.

    Jeff






^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-14 14:02                           ` Pavel Machek
@ 2002-03-15 11:13                             ` Vojtech Pavlik
  2002-03-18 19:21                               ` Pavel Machek
  0 siblings, 1 reply; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-15 11:13 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Martin Dalecki, LKML

On Thu, Mar 14, 2002 at 02:02:11PM +0000, Pavel Machek wrote:

> > You may happen to have the numbers, though - that should be enough.
> > 
> > Btw, I have a CMD640B based PCI card lying around here, but never
> > managed to get it generate any interrupts, though the rest seems to be
> > working.
> 
> Attach it to the timer interrupt -- that should do it for testing. Simplest
> way is to make ide timeouts HZ/100 and killing "lost interrupt" msg ;-).

Well, it seems like we'll have to something like this anyway. Some chips
sometimes forget to assert the IRQ after a transfer due to HW bugs, and
some PIIX3s are reported to do it quite often.

-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-14 14:13                               ` Pavel Machek
  2002-03-15 11:05                                 ` Jeff Garzik
@ 2002-03-15 14:45                                 ` Alan Cox
  1 sibling, 0 replies; 107+ messages in thread
From: Alan Cox @ 2002-03-15 14:45 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Jeff Garzik, Olivier Galibert, LKML

> >  s/CAP_SYS_RAWIO/CAP_DEVICE_CMD/ for the raw cmd ioctl interface.  Have 
> 
> Nobody uses capabilities these days, right?

Wrong. There are quite a few people using them, including large scale projects
and actual sold packages. For other reasons CAP_DEVICE_CMD doesn't work out

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-15 11:05                                 ` Jeff Garzik
@ 2002-03-18 19:20                                   ` Pavel Machek
  2002-03-19  9:29                                     ` Vojtech Pavlik
  0 siblings, 1 reply; 107+ messages in thread
From: Pavel Machek @ 2002-03-18 19:20 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Olivier Galibert, LKML

Hi!

> >>Under more restricted domains, root cannot bit-bang the interface. 
> >>s/CAP_SYS_RAWIO/CAP_DEVICE_CMD/ for the raw cmd ioctl interface.  Have 
> >>
> >
> >Nobody uses capabilities these days, right?
> 
> Actually, the NSA and HP secure linux products do, at the very least. 
> And there is some ELF capabilities project out there IIRC, but I dunno 
> if anybody's using it.

I did ELF capabilities ;-). And no, I do not think I had many users.

> commands.  With the proper sequencing, you can even do power management 
> of the drives in userspace.  You don't want to do system suspend/resume 
> that way, but you can certainly have a userspace policy daemon running, 
> that powers-down and powers-up the drives, etc.

See noflushd, Hdparm is able to powersave disks well, already, and it
was in 2.2.X, too.
									Pavel
-- 
(about SSSCA) "I don't say this lightly.  However, I really think that the U.S.
no longer is classifiable as a democracy, but rather as a plutocracy." --hpa

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-15 11:13                             ` Vojtech Pavlik
@ 2002-03-18 19:21                               ` Pavel Machek
  0 siblings, 0 replies; 107+ messages in thread
From: Pavel Machek @ 2002-03-18 19:21 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Martin Dalecki, LKML

Hi!

> > > You may happen to have the numbers, though - that should be enough.
> > > 
> > > Btw, I have a CMD640B based PCI card lying around here, but never
> > > managed to get it generate any interrupts, though the rest seems to be
> > > working.
> > 
> > Attach it to the timer interrupt -- that should do it for testing. Simplest
> > way is to make ide timeouts HZ/100 and killing "lost interrupt" msg ;-).
> 
> Well, it seems like we'll have to something like this anyway. Some chips
> sometimes forget to assert the IRQ after a transfer due to HW bugs, and
> some PIIX3s are reported to do it quite often.

What is "quite often"? Unless it is more than once in a hour, current
code is just okay... (It waits for timeout, which is about 30 sec?,
then recovers).
									Pavel
-- 
(about SSSCA) "I don't say this lightly.  However, I really think that the U.S.
no longer is classifiable as a democracy, but rather as a plutocracy." --hpa

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-18 19:20                                   ` Pavel Machek
@ 2002-03-19  9:29                                     ` Vojtech Pavlik
  2002-03-19 21:21                                       ` Pavel Machek
  0 siblings, 1 reply; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-19  9:29 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Jeff Garzik, Olivier Galibert, LKML

On Mon, Mar 18, 2002 at 08:20:05PM +0100, Pavel Machek wrote:
> > commands.  With the proper sequencing, you can even do power management 
> > of the drives in userspace.  You don't want to do system suspend/resume 
> > that way, but you can certainly have a userspace policy daemon running, 
> > that powers-down and powers-up the drives, etc.
> 
> See noflushd, Hdparm is able to powersave disks well, already, and it
> was in 2.2.X, too.

Not all of them safely, though. Many a drive will corrupt data if it
receives a command when not spinned up. You need to issue a wake command
first, which hdparm doesn't, it just leaves it to the kernel to issue a
read command or whatever to wake the drive ...

-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-19  9:29                                     ` Vojtech Pavlik
@ 2002-03-19 21:21                                       ` Pavel Machek
  2002-03-19 21:56                                         ` Vojtech Pavlik
                                                           ` (2 more replies)
  0 siblings, 3 replies; 107+ messages in thread
From: Pavel Machek @ 2002-03-19 21:21 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Pavel Machek, Jeff Garzik, Olivier Galibert, LKML

Hi!

> > > commands.  With the proper sequencing, you can even do power management 
> > > of the drives in userspace.  You don't want to do system suspend/resume 
> > > that way, but you can certainly have a userspace policy daemon running, 
> > > that powers-down and powers-up the drives, etc.
> > 
> > See noflushd, Hdparm is able to powersave disks well, already, and it
> > was in 2.2.X, too.
> 
> Not all of them safely, though. Many a drive will corrupt data if it
> receives a command when not spinned up. You need to issue a wake command
> first, which hdparm doesn't, it just leaves it to the kernel to issue a
> read command or whatever to wake the drive ...

Is this common disk bug, or are they permitted to behave like that?

									Pavel
-- 
Casualities in World Trade Center: ~3k dead inside the building,
cryptography in U.S.A. and free speech in Czech Republic.

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-19 21:21                                       ` Pavel Machek
@ 2002-03-19 21:56                                         ` Vojtech Pavlik
  2002-03-20  8:00                                           ` Daniela Engert
  2002-03-19 22:33                                         ` Andre Hedrick
  2002-03-20  0:25                                         ` Alan Cox
  2 siblings, 1 reply; 107+ messages in thread
From: Vojtech Pavlik @ 2002-03-19 21:56 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Vojtech Pavlik, Jeff Garzik, Olivier Galibert, LKML

On Tue, Mar 19, 2002 at 10:21:30PM +0100, Pavel Machek wrote:
> Hi!
> 
> > > > commands.  With the proper sequencing, you can even do power management 
> > > > of the drives in userspace.  You don't want to do system suspend/resume 
> > > > that way, but you can certainly have a userspace policy daemon running, 
> > > > that powers-down and powers-up the drives, etc.
> > > 
> > > See noflushd, Hdparm is able to powersave disks well, already, and it
> > > was in 2.2.X, too.
> > 
> > Not all of them safely, though. Many a drive will corrupt data if it
> > receives a command when not spinned up. You need to issue a wake command
> > first, which hdparm doesn't, it just leaves it to the kernel to issue a
> > read command or whatever to wake the drive ...
> 
> Is this common disk bug, or are they permitted to behave like that?

This behavior is permitted by the specification, as far as I know -
results of commands other than wakeup (and other pm commands) in sleep
or suspend mode are undefined ...

-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-19 21:21                                       ` Pavel Machek
  2002-03-19 21:56                                         ` Vojtech Pavlik
@ 2002-03-19 22:33                                         ` Andre Hedrick
  2002-03-20  0:25                                         ` Alan Cox
  2 siblings, 0 replies; 107+ messages in thread
From: Andre Hedrick @ 2002-03-19 22:33 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Vojtech Pavlik, Jeff Garzik, Olivier Galibert, LKML


Pavel,

No, it is called being a "BAD HOST".  Things were added before the
infrastructure was complete to support feature.  Thus the feature is now a
BUG.  Sorry but that is the simple true, one of the reasons why I asked
you to delay but it is not important now.

Regards,

Andre Hedrick
Linux Disk Certification Project                Linux ATA Development

On Tue, 19 Mar 2002, Pavel Machek wrote:

> Hi!
> 
> > > > commands.  With the proper sequencing, you can even do power management 
> > > > of the drives in userspace.  You don't want to do system suspend/resume 
> > > > that way, but you can certainly have a userspace policy daemon running, 
> > > > that powers-down and powers-up the drives, etc.
> > > 
> > > See noflushd, Hdparm is able to powersave disks well, already, and it
> > > was in 2.2.X, too.
> > 
> > Not all of them safely, though. Many a drive will corrupt data if it
> > receives a command when not spinned up. You need to issue a wake command
> > first, which hdparm doesn't, it just leaves it to the kernel to issue a
> > read command or whatever to wake the drive ...
> 
> Is this common disk bug, or are they permitted to behave like that?
> 
> 									Pavel
> -- 
> Casualities in World Trade Center: ~3k dead inside the building,
> cryptography in U.S.A. and free speech in Czech Republic.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-19 21:21                                       ` Pavel Machek
  2002-03-19 21:56                                         ` Vojtech Pavlik
  2002-03-19 22:33                                         ` Andre Hedrick
@ 2002-03-20  0:25                                         ` Alan Cox
  2 siblings, 0 replies; 107+ messages in thread
From: Alan Cox @ 2002-03-20  0:25 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Vojtech Pavlik, Pavel Machek, Jeff Garzik, Olivier Galibert, LKML

> > receives a command when not spinned up. You need to issue a wake command
> > first, which hdparm doesn't, it just leaves it to the kernel to issue a
> > read command or whatever to wake the drive ...
> 
> Is this common disk bug, or are they permitted to behave like that?

Its not that common, but these sort of things happen sometimes. IDE is
very much a defensive driver 

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-19 21:56                                         ` Vojtech Pavlik
@ 2002-03-20  8:00                                           ` Daniela Engert
  2002-03-20 18:11                                             ` Bill Davidsen
  2002-03-20 22:15                                             ` Pavel Machek
  0 siblings, 2 replies; 107+ messages in thread
From: Daniela Engert @ 2002-03-20  8:00 UTC (permalink / raw)
  To: Pavel Machek, Vojtech Pavlik
  Cc: Jeff Garzik, LKML, Olivier Galibert, Vojtech Pavlik

On Tue, 19 Mar 2002 22:56:09 +0100, Vojtech Pavlik wrote:

>> > Not all of them safely, though. Many a drive will corrupt data if it
>> > receives a command when not spinned up. You need to issue a wake command
>> > first, which hdparm doesn't, it just leaves it to the kernel to issue a
>> > read command or whatever to wake the drive ...
>> 
>> Is this common disk bug, or are they permitted to behave like that?
>
>This behavior is permitted by the specification, as far as I know -

Actually not. Have a look at page 36 of the current ATA6 specification.


>results of commands other than wakeup (and other pm commands) in sleep
>or suspend mode are undefined ...

If a disk is in power state PM1:idle or PM2:standby, each ATA command
which requires media access will result in a transition to power state
PM0:active as well. The driver should be prepared of a long command
execution time in this case (due to the spin up delay). This is why a
well implemented ATA driver should track the individual power states of
each attached unit to modulate its internal command timeout
accordingly.

The driver may issue a SET_FEATURES(spin up) command in anticipation of
a media access. A "forgiving" implementation might issue this command
at proper system state transitions as well .

If a disk has entered power state PM3:sleep, its interface is turned
off! You no longer can issue any command except for a DEVICE RESET to
this unit. A reset is required to initiate a state transition from
PM3:sleep to PM2:standby (there are no other state transitions).

Ciao,
  Dani

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Daniela Engert, systems engineer at MEDAV GmbH
Gräfenberger Str. 34, 91080 Uttenreuth, Germany
Phone ++49-9131-583-348, Fax ++49-9131-583-11



^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-20  8:00                                           ` Daniela Engert
@ 2002-03-20 18:11                                             ` Bill Davidsen
  2002-03-20 18:46                                               ` Daniela Engert
  2002-03-20 22:15                                             ` Pavel Machek
  1 sibling, 1 reply; 107+ messages in thread
From: Bill Davidsen @ 2002-03-20 18:11 UTC (permalink / raw)
  To: Daniela Engert; +Cc: LKML

On Wed, 20 Mar 2002, Daniela Engert wrote:

> >This behavior is permitted by the specification, as far as I know -
> 
> Actually not. Have a look at page 36 of the current ATA6 specification.

That's probably not the place to look, since drives will conform to the
specs in place when they were designed. If older specs did not require
automatic spinup, then ATA6 doesn't apply.

In the real world I have seen drives which definitely didn't like commands
in spindown, so unless there is some really large penalty for sending that
I would suggest having the logic support the existing hardware. We still
have 386 and FPE emulation, I would bet there are more older drives than
386s in use (at least by my clients ;-).

-- 
bill davidsen <davidsen@tmr.com>
  CTO, TMR Associates, Inc
Doing interesting things with little computers since 1979.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-20 18:11                                             ` Bill Davidsen
@ 2002-03-20 18:46                                               ` Daniela Engert
  0 siblings, 0 replies; 107+ messages in thread
From: Daniela Engert @ 2002-03-20 18:46 UTC (permalink / raw)
  To: Bill Davidsen; +Cc: LKML

On Wed, 20 Mar 2002 13:11:03 -0500 (EST), Bill Davidsen wrote:

>On Wed, 20 Mar 2002, Daniela Engert wrote:
>
>> >This behavior is permitted by the specification, as far as I know -
>> 
>> Actually not. Have a look at page 36 of the current ATA6 specification.
>
>That's probably not the place to look, since drives will conform to the
>specs in place when they were designed. If older specs did not require
>automatic spinup, then ATA6 doesn't apply.

Well, then have a look at page 31 of the ATA3 spec. It tells you
basically the same - just a little more terse ;-)

Ciao,
  Dani



^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-20  8:00                                           ` Daniela Engert
  2002-03-20 18:11                                             ` Bill Davidsen
@ 2002-03-20 22:15                                             ` Pavel Machek
  2002-03-20 23:09                                               ` Daniel Kobras
  1 sibling, 1 reply; 107+ messages in thread
From: Pavel Machek @ 2002-03-20 22:15 UTC (permalink / raw)
  To: Daniela Engert; +Cc: Vojtech Pavlik, Jeff Garzik, LKML, Olivier Galibert

Hi!

> >> > Not all of them safely, though. Many a drive will corrupt data if it
> >> > receives a command when not spinned up. You need to issue a wake command
> >> > first, which hdparm doesn't, it just leaves it to the kernel to issue a
> >> > read command or whatever to wake the drive ...
> >> 
> >> Is this common disk bug, or are they permitted to behave like that?
> >
> >This behavior is permitted by the specification, as far as I know -
> 
> Actually not. Have a look at page 36 of the current ATA6
> specification.

Good. So noflushd is safe.
								Pavel

> If a disk has entered power state PM3:sleep, its interface is turned
> off! You no longer can issue any command except for a DEVICE RESET to
> this unit. A reset is required to initiate a state transition from
> PM3:sleep to PM2:standby (there are no other state transitions).

I do not think we are using PM3:sleep in noflushd, but we even
could. AFAICT, ide layer resets interface if it does not respond.

-- 
Casualities in World Trade Center: ~3k dead inside the building,
cryptography in U.S.A. and free speech in Czech Republic.

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [patch] My AMD IDE driver, v2.7
  2002-03-20 22:15                                             ` Pavel Machek
@ 2002-03-20 23:09                                               ` Daniel Kobras
  0 siblings, 0 replies; 107+ messages in thread
From: Daniel Kobras @ 2002-03-20 23:09 UTC (permalink / raw)
  To: LKML

On Wed, Mar 20, 2002 at 11:15:14PM +0100, Pavel Machek wrote:
> I do not think we are using PM3:sleep in noflushd, but we even
> could. AFAICT, ide layer resets interface if it does not respond.

It does, but only after a rather longish timeout, and a couple of IDE
errors in the syslog.  Nothing I'd like to scare users with, so noflushd
issues standby (PM2).

Regards,

Daniel.


^ permalink raw reply	[flat|nested] 107+ messages in thread

end of thread, other threads:[~2002-03-20 23:09 UTC | newest]

Thread overview: 107+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-03-11 15:13 [patch] My AMD IDE driver, v2.7 Vojtech Pavlik
2002-03-11 16:36 ` Martin Dalecki
2002-03-11 20:49   ` Rik van Riel
2002-03-11 22:45     ` Alan Cox
2002-03-11 22:39       ` Linus Torvalds
2002-03-11 22:45         ` Vojtech Pavlik
2002-03-11 22:53           ` Linus Torvalds
2002-03-12  0:14             ` Bill Davidsen
2002-03-12  0:34               ` Jeff Garzik
2002-03-12  0:58                 ` Erik Andersen
2002-03-12  1:33                   ` Jeff Garzik
2002-03-12  1:41                     ` Linus Torvalds
2002-03-12  1:50                       ` Jeff Garzik
2002-03-11 18:50                         ` gmack
2002-03-12  2:19                         ` Linus Torvalds
2002-03-12  2:34                           ` Jeff Garzik
2002-03-12 11:21                             ` Martin Dalecki
2002-03-12  2:54                           ` J. Dow
2002-03-12  6:32                           ` Vojtech Pavlik
2002-03-14 15:12                             ` Pavel Machek
2002-03-13 18:42                         ` Horst von Brand
2002-03-13 19:11                           ` Andre Hedrick
2002-03-12  6:25                     ` Vojtech Pavlik
2002-03-12  7:13                   ` Erik Andersen
2002-03-12 16:40                 ` Bill Davidsen
2002-03-12  0:51               ` Linus Torvalds
2002-03-12  1:41                 ` Jeff Garzik
2002-03-12  1:44                   ` Linus Torvalds
2002-03-12  2:22                     ` Jeff Garzik
2002-03-12  2:33                       ` Linus Torvalds
2002-03-12  2:37                         ` Jeff Garzik
2002-03-12  3:34                           ` Olivier Galibert
2002-03-12  4:13                             ` Jeff Garzik
2002-03-14 14:13                               ` Pavel Machek
2002-03-15 11:05                                 ` Jeff Garzik
2002-03-18 19:20                                   ` Pavel Machek
2002-03-19  9:29                                     ` Vojtech Pavlik
2002-03-19 21:21                                       ` Pavel Machek
2002-03-19 21:56                                         ` Vojtech Pavlik
2002-03-20  8:00                                           ` Daniela Engert
2002-03-20 18:11                                             ` Bill Davidsen
2002-03-20 18:46                                               ` Daniela Engert
2002-03-20 22:15                                             ` Pavel Machek
2002-03-20 23:09                                               ` Daniel Kobras
2002-03-19 22:33                                         ` Andre Hedrick
2002-03-20  0:25                                         ` Alan Cox
2002-03-15 14:45                                 ` Alan Cox
2002-03-12 11:23                           ` Martin Dalecki
2002-03-12  2:50                       ` J. Dow
2002-03-12  3:10                         ` Jeff Garzik
2002-03-12  3:28                           ` Linus Torvalds
2002-03-12  3:46                             ` Jeff Garzik
2002-03-12  6:10                               ` J. Dow
2002-03-12  3:58                             ` Linus Torvalds
2002-03-12  4:26                               ` Jeff Garzik
2002-03-12  4:40                                 ` Linus Torvalds
2002-03-12  6:26                                 ` J. Dow
2002-03-12 11:44                                   ` Martin Dalecki
2002-03-12  4:31                               ` Linus Torvalds
2002-03-12  5:05                                 ` Jeff Garzik
2002-03-12  5:20                                   ` Linus Torvalds
2002-03-12 11:39                                 ` Martin Dalecki
2002-03-12  4:49                               ` Erik Andersen
2002-03-12  5:08                                 ` Linus Torvalds
2002-03-12 11:36                               ` Martin Dalecki
2002-03-12  6:05                             ` J. Dow
2002-03-12  4:41                           ` Erik Andersen
2002-03-12  4:48                             ` Jeff Garzik
2002-03-12  6:30                               ` J. Dow
2002-03-12  6:29                             ` J. Dow
2002-03-12 16:36                             ` Bill Davidsen
2002-03-12  2:57                   ` Alan Cox
2002-03-12  2:49                     ` Jeff Garzik
2002-03-12 11:17                       ` Alan Cox
2002-03-13  8:14                       ` ide filters / 'ide dump' / 'bio dump' bert hubert
2002-03-13 10:11                         ` Jeff Garzik
2002-03-13 12:05                           ` Malcolm Beattie
2002-03-13 17:17                           ` Linus Torvalds
2002-03-12 11:10                   ` [patch] My AMD IDE driver, v2.7 Martin Dalecki
2002-03-12  0:33                     ` benh
2002-03-12 20:21                   ` Gunther Mayer
2002-03-12 16:33                 ` Bill Davidsen
2002-03-12 11:00           ` Martin Dalecki
2002-03-12 15:59             ` Vojtech Pavlik
2002-03-12 16:11               ` Martin Dalecki
2002-03-12 16:21                 ` Vojtech Pavlik
2002-03-12 16:26                   ` Martin Dalecki
2002-03-12 16:33                     ` Vojtech Pavlik
2002-03-12 16:41                       ` Martin Dalecki
2002-03-13  0:01                         ` Russell King
2002-03-12 16:43                       ` Martin Dalecki
2002-03-12 16:50                         ` Vojtech Pavlik
2002-03-12 16:58                           ` Martin Dalecki
2002-03-14 14:02                           ` Pavel Machek
2002-03-15 11:13                             ` Vojtech Pavlik
2002-03-18 19:21                               ` Pavel Machek
2002-03-13 19:43                   ` Bill Davidsen
2002-03-12 16:44                 ` Sebastian Droege
2002-03-12 16:17               ` Martin Dalecki
2002-03-12 16:27                 ` Vojtech Pavlik
2002-03-12 16:32                   ` Martin Dalecki
2002-03-12 20:00             ` [patch] PIIX driver rewrite Vojtech Pavlik
2002-03-12 20:35             ` Sebastian Droege
2002-03-12 20:34               ` Vojtech Pavlik
2002-03-12 21:07               ` Sebastian Droege
2002-03-12 21:19                 ` Vojtech Pavlik
2002-03-11 23:01         ` [patch] My AMD IDE driver, v2.7 Alan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).