All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/15] IDE quilt tree updated
@ 2007-01-19  0:30 Bartlomiej Zolnierkiewicz
  2007-01-19  0:31 ` [PATCH 1/15] ACPI support for IDE devices Bartlomiej Zolnierkiewicz
                   ` (14 more replies)
  0 siblings, 15 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:30 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel


Hi,

I've just updated IDE quilt tree:
	http://kernel.org/pub/linux/kernel/people/bart/pata-2.6/patches/


New patches:

* IDE driver for Delkin/Lexar/ASKA/Workbit/etc. CardBus CF adapters
  (Mark Lord <mlord@pobox.com>)

* ACPI support for IDE devices
  (Hannes Reinecke <hare@suse.de>)

* ide: unregister ide-pnp driver on unload
  (Tejun Heo <htejun@gmail.com>)

* via82cxxx/pata_via: correct PCI_DEVICE_ID_VIA_SATA_EIDE ID and add support
  for CX700 and 8237S
  (Josepch Chan <josephchan@via.com.tw>)

* rework of the code selecting the best DMA transfer mode (~500 LOCs less)
  (me)

* some misc fixes/cleanups (me)

diffstat:
 68 files changed, 3310 insertions(+), 2495 deletions(-)


I'm sending only new patches for review/comments.

If you would like to see the full quilt series (or to get combined patch)
against 2.6.20-rc5, they are available here:

       http://kernel.org/pub/linux/kernel/people/bart/pata-2.6/releases/

Thanks,
Bart

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

* [PATCH 1/15] ACPI support for IDE devices
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:31 ` Bartlomiej Zolnierkiewicz
  2007-01-19  0:31 ` [PATCH 2/15] via82cxxx/pata_via: correct PCI_DEVICE_ID_VIA_SATA_EIDE ID and add support for CX700 and 8237S Bartlomiej Zolnierkiewicz
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:31 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] ACPI support for IDE devices

This patch implements ACPI integration for generic IDE devices.
The ACPI spec mandates that some methods are called during suspend and
resume. And consequently there most modern Laptops cannot resume
properly without it.

According to the spec, we should call '_GTM' (Get Timing) upon suspend
to store the current IDE adapter settings.
Upon resume we should call '_STM' (Set Timing) to initialize the
adapter with the stored settings; afterwards '_GTF' (Get Taskfile)
should be called which returns a buffer with some IDE initialisation
commands. Those commands should be passed to the drive.

There are two module params which control the behaviour of this patch:

'ide=noacpi'
	Do not call any ACPI methods (Disables any ACPI method calls)
'ide=acpigtf'
	Enable execution of _GTF methods upon resume.
	Has no effect if 'ide=noacpi' is set.
'ide=acpionboot'
	Enable execution of ACPI methods during boot.
	This might be required on some machines if 'ide=acpigtf' is
	selected as some machines modify the _GTF information
	depending on the drive identification passed down with _STM.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/Kconfig     |    7 
 drivers/ide/Makefile    |    1 
 drivers/ide/ide-acpi.c  |  696 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/ide/ide-probe.c |    3 
 drivers/ide/ide.c       |   36 ++
 include/linux/ide.h     |   27 +
 6 files changed, 770 insertions(+)

Index: b/drivers/ide/Kconfig
===================================================================
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -271,6 +271,13 @@ config BLK_DEV_IDESCSI
 	  If both this SCSI emulation and native ATAPI support are compiled
 	  into the kernel, the native support will be used.
 
+config BLK_DEV_IDEACPI
+	bool "IDE ACPI support"
+	depends on ACPI
+	---help---
+	  Implement ACPI support for generic IDE devices. On modern
+	  machines ACPI support is required to properly handle ACPI S3 states.
+
 config IDE_TASK_IOCTL
 	bool "IDE Taskfile Access"
 	help
Index: b/drivers/ide/Makefile
===================================================================
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -22,6 +22,7 @@ ide-core-$(CONFIG_BLK_DEV_IDEPCI)	+= set
 ide-core-$(CONFIG_BLK_DEV_IDEDMA)	+= ide-dma.o
 ide-core-$(CONFIG_PROC_FS)		+= ide-proc.o
 ide-core-$(CONFIG_BLK_DEV_IDEPNP)	+= ide-pnp.o
+ide-core-$(CONFIG_BLK_DEV_IDEACPI)	+= ide-acpi.o
 
 # built-in only drivers from arm/
 ide-core-$(CONFIG_IDE_ARM)		+= arm/ide_arm.o
Index: b/drivers/ide/ide-acpi.c
===================================================================
--- /dev/null
+++ b/drivers/ide/ide-acpi.c
@@ -0,0 +1,696 @@
+/*
+ * ide-acpi.c
+ * Provides ACPI support for IDE drives.
+ *
+ * Copyright (C) 2005 Intel Corp.
+ * Copyright (C) 2005 Randy Dunlap
+ * Copyright (C) 2006 SUSE Linux Products GmbH
+ * Copyright (C) 2006 Hannes Reinecke
+ */
+
+#include <linux/ata.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <acpi/acpi.h>
+#include <linux/ide.h>
+#include <linux/pci.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acnames.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+#include <acpi/acexcep.h>
+#include <acpi/acmacros.h>
+#include <acpi/actypes.h>
+
+#define REGS_PER_GTF		7
+struct taskfile_array {
+	u8	tfa[REGS_PER_GTF];	/* regs. 0x1f1 - 0x1f7 */
+};
+
+struct GTM_buffer {
+	u32	PIO_speed0;
+	u32	DMA_speed0;
+	u32	PIO_speed1;
+	u32	DMA_speed1;
+	u32	GTM_flags;
+};
+
+struct ide_acpi_drive_link {
+	ide_drive_t	*drive;
+	acpi_handle	 obj_handle;
+	u8		 idbuff[512];
+};
+
+struct ide_acpi_hwif_link {
+	ide_hwif_t			*hwif;
+	acpi_handle			 obj_handle;
+	struct GTM_buffer		 gtm;
+	struct ide_acpi_drive_link	 master;
+	struct ide_acpi_drive_link	 slave;
+};
+
+#undef DEBUGGING
+/* note: adds function name and KERN_DEBUG */
+#ifdef DEBUGGING
+#define DEBPRINT(fmt, args...)	\
+		printk(KERN_DEBUG "%s: " fmt, __FUNCTION__, ## args)
+#else
+#define DEBPRINT(fmt, args...)	do {} while (0)
+#endif	/* DEBUGGING */
+
+extern int ide_noacpi;
+extern int ide_noacpitfs;
+extern int ide_noacpionboot;
+
+/**
+ * ide_get_dev_handle - finds acpi_handle and PCI device.function
+ * @dev: device to locate
+ * @handle: returned acpi_handle for @dev
+ * @pcidevfn: return PCI device.func for @dev
+ *
+ * Returns the ACPI object handle to the corresponding PCI device.
+ *
+ * Returns 0 on success, <0 on error.
+ */
+static int ide_get_dev_handle(struct device *dev, acpi_handle *handle,
+			       acpi_integer *pcidevfn)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	unsigned int bus, devnum, func;
+	acpi_integer addr;
+	acpi_handle dev_handle;
+	struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER,
+					.pointer = NULL};
+	acpi_status status;
+	struct acpi_device_info	*dinfo = NULL;
+	int ret = -ENODEV;
+
+	bus = pdev->bus->number;
+	devnum = PCI_SLOT(pdev->devfn);
+	func = PCI_FUNC(pdev->devfn);
+	/* ACPI _ADR encoding for PCI bus: */
+	addr = (acpi_integer)(devnum << 16 | func);
+
+	DEBPRINT("ENTER: pci %02x:%02x.%01x\n", bus, devnum, func);
+
+	dev_handle = DEVICE_ACPI_HANDLE(dev);
+	if (!dev_handle) {
+		DEBPRINT("no acpi handle for device\n");
+		goto err;
+	}
+
+	status = acpi_get_object_info(dev_handle, &buffer);
+	if (ACPI_FAILURE(status)) {
+		DEBPRINT("get_object_info for device failed\n");
+		goto err;
+	}
+	dinfo = buffer.pointer;
+	if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
+	    dinfo->address == addr) {
+		*pcidevfn = addr;
+		*handle = dev_handle;
+	} else {
+		DEBPRINT("get_object_info for device has wrong "
+			" address: %llu, should be %u\n",
+			dinfo ? (unsigned long long)dinfo->address : -1ULL,
+			(unsigned int)addr);
+		goto err;
+	}
+
+	DEBPRINT("for dev=0x%x.%x, addr=0x%llx, *handle=0x%p\n",
+		 devnum, func, (unsigned long long)addr, *handle);
+	ret = 0;
+err:
+	kfree(dinfo);
+	return ret;
+}
+
+/**
+ * ide_acpi_hwif_get_handle - Get ACPI object handle for a given hwif
+ * @hwif: device to locate
+ *
+ * Retrieves the object handle for a given hwif.
+ *
+ * Returns handle on success, 0 on error.
+ */
+static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif)
+{
+	struct device		*dev = hwif->gendev.parent;
+	acpi_handle		dev_handle;
+	acpi_integer		pcidevfn;
+	acpi_handle		chan_handle;
+	int			err;
+
+	DEBPRINT("ENTER: device %s\n", hwif->name);
+
+	if (!dev) {
+		DEBPRINT("no PCI device for %s\n", hwif->name);
+		return NULL;
+	}
+
+	err = ide_get_dev_handle(dev, &dev_handle, &pcidevfn);
+	if (err < 0) {
+		DEBPRINT("ide_get_dev_handle failed (%d)\n", err);
+		return NULL;
+	}
+
+	/* get child objects of dev_handle == channel objects,
+	 * + _their_ children == drive objects */
+	/* channel is hwif->channel */
+	chan_handle = acpi_get_child(dev_handle, hwif->channel);
+	DEBPRINT("chan adr=%d: handle=0x%p\n",
+		 hwif->channel, chan_handle);
+
+	return chan_handle;
+}
+
+/**
+ * ide_acpi_drive_get_handle - Get ACPI object handle for a given drive
+ * @drive: device to locate
+ *
+ * Retrieves the object handle of a given drive. According to the ACPI
+ * spec the drive is a child of the hwif.
+ *
+ * Returns handle on success, 0 on error.
+ */
+static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive)
+{
+	ide_hwif_t	*hwif = HWIF(drive);
+	int		 port;
+	acpi_handle	 drive_handle;
+
+	if (!hwif->acpidata)
+		return NULL;
+
+	if (!hwif->acpidata->obj_handle)
+		return NULL;
+
+	port = hwif->channel ? drive->dn - 2: drive->dn;
+
+	DEBPRINT("ENTER: %s at channel#: %d port#: %d\n",
+		 drive->name, hwif->channel, port);
+
+
+	/* TBD: could also check ACPI object VALID bits */
+	drive_handle = acpi_get_child(hwif->acpidata->obj_handle, port);
+	DEBPRINT("drive %s handle 0x%p\n", drive->name, drive_handle);
+
+	return drive_handle;
+}
+
+/**
+ * do_drive_get_GTF - get the drive bootup default taskfile settings
+ * @drive: the drive for which the taskfile settings should be retrieved
+ * @gtf_length: number of bytes of _GTF data returned at @gtf_address
+ * @gtf_address: buffer containing _GTF taskfile arrays
+ *
+ * The _GTF method has no input parameters.
+ * It returns a variable number of register set values (registers
+ * hex 1F1..1F7, taskfiles).
+ * The <variable number> is not known in advance, so have ACPI-CA
+ * allocate the buffer as needed and return it, then free it later.
+ *
+ * The returned @gtf_length and @gtf_address are only valid if the
+ * function return value is 0.
+ */
+static int do_drive_get_GTF(ide_drive_t *drive,
+		     unsigned int *gtf_length, unsigned long *gtf_address,
+		     unsigned long *obj_loc)
+{
+	acpi_status			status;
+	struct acpi_buffer		output;
+	union acpi_object 		*out_obj;
+	ide_hwif_t			*hwif = HWIF(drive);
+	struct device			*dev = hwif->gendev.parent;
+	int				err = -ENODEV;
+	int				port;
+
+	*gtf_length = 0;
+	*gtf_address = 0UL;
+	*obj_loc = 0UL;
+
+	if (ide_noacpi)
+		return 0;
+
+	if (!dev) {
+		DEBPRINT("no PCI device for %s\n", hwif->name);
+		goto out;
+	}
+
+	if (!hwif->acpidata) {
+		DEBPRINT("no ACPI data for %s\n", hwif->name);
+		goto out;
+	}
+
+	port = hwif->channel ? drive->dn - 2: drive->dn;
+
+	if (!drive->acpidata) {
+		if (port == 0) {
+			drive->acpidata = &hwif->acpidata->master;
+			hwif->acpidata->master.drive = drive;
+		} else {
+			drive->acpidata = &hwif->acpidata->slave;
+			hwif->acpidata->slave.drive = drive;
+		}
+	}
+
+	DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n",
+		 hwif->name, dev->bus_id, port, hwif->channel);
+
+	if (!drive->present) {
+		DEBPRINT("%s drive %d:%d not present\n",
+			 hwif->name, hwif->channel, port);
+		goto out;
+	}
+
+	/* Get this drive's _ADR info. if not already known. */
+	if (!drive->acpidata->obj_handle) {
+		drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
+		if (!drive->acpidata->obj_handle) {
+			DEBPRINT("No ACPI object found for %s\n",
+				 drive->name);
+			goto out;
+		}
+	}
+
+	/* Setting up output buffer */
+	output.length = ACPI_ALLOCATE_BUFFER;
+	output.pointer = NULL;	/* ACPI-CA sets this; save/free it later */
+
+	/* _GTF has no input parameters */
+	err = -EIO;
+	status = acpi_evaluate_object(drive->acpidata->obj_handle, "_GTF",
+				      NULL, &output);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_DEBUG
+		       "%s: Run _GTF error: status = 0x%x\n",
+		       __FUNCTION__, status);
+		goto out;
+	}
+
+	if (!output.length || !output.pointer) {
+		DEBPRINT("Run _GTF: "
+		       "length or ptr is NULL (0x%llx, 0x%p)\n",
+		       (unsigned long long)output.length,
+		       output.pointer);
+		goto out;
+	}
+
+	out_obj = output.pointer;
+	if (out_obj->type != ACPI_TYPE_BUFFER) {
+		DEBPRINT("Run _GTF: error: "
+		       "expected object type of ACPI_TYPE_BUFFER, "
+		       "got 0x%x\n", out_obj->type);
+		err = -ENOENT;
+		kfree(output.pointer);
+		goto out;
+	}
+
+	if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
+	    out_obj->buffer.length % REGS_PER_GTF) {
+		printk(KERN_ERR
+		       "%s: unexpected GTF length (%d) or addr (0x%p)\n",
+		       __FUNCTION__, out_obj->buffer.length,
+		       out_obj->buffer.pointer);
+		err = -ENOENT;
+		kfree(output.pointer);
+		goto out;
+	}
+
+	*gtf_length = out_obj->buffer.length;
+	*gtf_address = (unsigned long)out_obj->buffer.pointer;
+	*obj_loc = (unsigned long)out_obj;
+	DEBPRINT("returning gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n",
+		 *gtf_length, *gtf_address, *obj_loc);
+	err = 0;
+out:
+	return err;
+}
+
+/**
+ * taskfile_load_raw - send taskfile registers to drive
+ * @drive: drive to which output is sent
+ * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
+ *
+ * Outputs IDE taskfile to the drive.
+ */
+static int taskfile_load_raw(ide_drive_t *drive,
+			      const struct taskfile_array *gtf)
+{
+	ide_task_t args;
+	int err = 0;
+
+	DEBPRINT("(0x1f1-1f7): hex: "
+	       "%02x %02x %02x %02x %02x %02x %02x\n",
+	       gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
+	       gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
+
+	memset(&args, 0, sizeof(ide_task_t));
+	args.command_type = IDE_DRIVE_TASK_NO_DATA;
+	args.data_phase   = TASKFILE_IN;
+	args.handler      = &task_no_data_intr;
+
+	/* convert gtf to IDE Taskfile */
+	args.tfRegister[1] = gtf->tfa[0];	/* 0x1f1 */
+	args.tfRegister[2] = gtf->tfa[1];	/* 0x1f2 */
+	args.tfRegister[3] = gtf->tfa[2];	/* 0x1f3 */
+	args.tfRegister[4] = gtf->tfa[3];	/* 0x1f4 */
+	args.tfRegister[5] = gtf->tfa[4];	/* 0x1f5 */
+	args.tfRegister[6] = gtf->tfa[5];	/* 0x1f6 */
+	args.tfRegister[7] = gtf->tfa[6];	/* 0x1f7 */
+
+	if (ide_noacpitfs) {
+		DEBPRINT("_GTF execution disabled\n");
+		return err;
+	}
+
+	err = ide_raw_taskfile(drive, &args, NULL);
+	if (err)
+		printk(KERN_ERR "%s: ide_raw_taskfile failed: %u\n",
+		       __FUNCTION__, err);
+
+	return err;
+}
+
+/**
+ * do_drive_set_taskfiles - write the drive taskfile settings from _GTF
+ * @drive: the drive to which the taskfile command should be sent
+ * @gtf_length: total number of bytes of _GTF taskfiles
+ * @gtf_address: location of _GTF taskfile arrays
+ *
+ * Write {gtf_address, length gtf_length} in groups of
+ * REGS_PER_GTF bytes.
+ */
+static int do_drive_set_taskfiles(ide_drive_t *drive,
+				  unsigned int gtf_length,
+				  unsigned long gtf_address)
+{
+	int			rc = -ENODEV, err;
+	int			gtf_count = gtf_length / REGS_PER_GTF;
+	int			ix;
+	struct taskfile_array	*gtf;
+
+	if (ide_noacpi)
+		return 0;
+
+	DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn);
+
+	if (!drive->present)
+		goto out;
+	if (!gtf_count)		/* shouldn't be here */
+		goto out;
+
+	DEBPRINT("total GTF bytes=%u (0x%x), gtf_count=%d, addr=0x%lx\n",
+		 gtf_length, gtf_length, gtf_count, gtf_address);
+
+	if (gtf_length % REGS_PER_GTF) {
+		printk(KERN_ERR "%s: unexpected GTF length (%d)\n",
+		       __FUNCTION__, gtf_length);
+		goto out;
+	}
+
+	rc = 0;
+	for (ix = 0; ix < gtf_count; ix++) {
+		gtf = (struct taskfile_array *)
+			(gtf_address + ix * REGS_PER_GTF);
+
+		/* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
+		err = taskfile_load_raw(drive, gtf);
+		if (err)
+			rc = err;
+	}
+
+out:
+	return rc;
+}
+
+/**
+ * ide_acpi_exec_tfs - get then write drive taskfile settings
+ * @drive: the drive for which the taskfile settings should be
+ *         written.
+ *
+ * According to the ACPI spec this should be called after _STM
+ * has been evaluated for the interface. Some ACPI vendors interpret
+ * that as a hard requirement and modify the taskfile according
+ * to the Identify Drive information passed down with _STM.
+ * So one should really make sure to call this only after _STM has
+ * been executed.
+ */
+int ide_acpi_exec_tfs(ide_drive_t *drive)
+{
+	int		ret;
+	unsigned int	gtf_length;
+	unsigned long	gtf_address;
+	unsigned long	obj_loc;
+
+	if (ide_noacpi)
+		return 0;
+
+	DEBPRINT("call get_GTF, drive=%s port=%d\n", drive->name, drive->dn);
+
+	ret = do_drive_get_GTF(drive, &gtf_length, &gtf_address, &obj_loc);
+	if (ret < 0) {
+		DEBPRINT("get_GTF error (%d)\n", ret);
+		return ret;
+	}
+
+	DEBPRINT("call set_taskfiles, drive=%s\n", drive->name);
+
+	ret = do_drive_set_taskfiles(drive, gtf_length, gtf_address);
+	kfree((void *)obj_loc);
+	if (ret < 0) {
+		DEBPRINT("set_taskfiles error (%d)\n", ret);
+	}
+
+	DEBPRINT("ret=%d\n", ret);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ide_acpi_exec_tfs);
+
+/**
+ * ide_acpi_get_timing - get the channel (controller) timings
+ * @hwif: target IDE interface (channel)
+ *
+ * This function executes the _GTM ACPI method for the target channel.
+ *
+ */
+void ide_acpi_get_timing(ide_hwif_t *hwif)
+{
+	acpi_status		status;
+	struct acpi_buffer	output;
+	union acpi_object 	*out_obj;
+
+	if (ide_noacpi)
+		return;
+
+	DEBPRINT("ENTER:\n");
+
+	if (!hwif->acpidata) {
+		DEBPRINT("no ACPI data for %s\n", hwif->name);
+		return;
+	}
+
+	/* Setting up output buffer for _GTM */
+	output.length = ACPI_ALLOCATE_BUFFER;
+	output.pointer = NULL;	/* ACPI-CA sets this; save/free it later */
+
+	/* _GTM has no input parameters */
+	status = acpi_evaluate_object(hwif->acpidata->obj_handle, "_GTM",
+				      NULL, &output);
+
+	DEBPRINT("_GTM status: %d, outptr: 0x%p, outlen: 0x%llx\n",
+		 status, output.pointer,
+		 (unsigned long long)output.length);
+
+	if (ACPI_FAILURE(status)) {
+		DEBPRINT("Run _GTM error: status = 0x%x\n", status);
+		return;
+	}
+
+	if (!output.length || !output.pointer) {
+		DEBPRINT("Run _GTM: length or ptr is NULL (0x%llx, 0x%p)\n",
+		       (unsigned long long)output.length,
+		       output.pointer);
+		kfree(output.pointer);
+		return;
+	}
+
+	out_obj = output.pointer;
+	if (out_obj->type != ACPI_TYPE_BUFFER) {
+		kfree(output.pointer);
+		DEBPRINT("Run _GTM: error: "
+		       "expected object type of ACPI_TYPE_BUFFER, "
+		       "got 0x%x\n", out_obj->type);
+		return;
+	}
+
+	if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
+	    out_obj->buffer.length != sizeof(struct GTM_buffer)) {
+		kfree(output.pointer);
+		printk(KERN_ERR
+		       "%s: unexpected _GTM length (0x%x)[should be 0x%x] or addr (0x%p)\n",
+		       __FUNCTION__, out_obj->buffer.length,
+		       sizeof(struct GTM_buffer), out_obj->buffer.pointer);
+		return;
+	}
+
+	memcpy(&hwif->acpidata->gtm, out_obj->buffer.pointer,
+	       sizeof(struct GTM_buffer));
+
+	DEBPRINT("_GTM info: ptr: 0x%p, len: 0x%x, exp.len: 0x%Zx\n",
+		 out_obj->buffer.pointer, out_obj->buffer.length,
+		 sizeof(struct GTM_buffer));
+
+	DEBPRINT("_GTM fields: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
+		 hwif->acpidata->gtm.PIO_speed0,
+		 hwif->acpidata->gtm.DMA_speed0,
+		 hwif->acpidata->gtm.PIO_speed1,
+		 hwif->acpidata->gtm.DMA_speed1,
+		 hwif->acpidata->gtm.GTM_flags);
+
+	kfree(output.pointer);
+}
+EXPORT_SYMBOL_GPL(ide_acpi_get_timing);
+
+/**
+ * ide_acpi_push_timing - set the channel (controller) timings
+ * @hwif: target IDE interface (channel)
+ *
+ * This function executes the _STM ACPI method for the target channel.
+ *
+ * _STM requires Identify Drive data, which has to passed as an argument.
+ * Unfortunately hd_driveid is a mangled version which we can't readily
+ * use; hence we'll get the information afresh.
+ */
+void ide_acpi_push_timing(ide_hwif_t *hwif)
+{
+	acpi_status		status;
+	struct acpi_object_list	input;
+	union acpi_object 	in_params[3];
+	struct ide_acpi_drive_link	*master = &hwif->acpidata->master;
+	struct ide_acpi_drive_link	*slave = &hwif->acpidata->slave;
+
+	if (ide_noacpi)
+		return;
+
+	DEBPRINT("ENTER:\n");
+
+	if (!hwif->acpidata) {
+		DEBPRINT("no ACPI data for %s\n", hwif->name);
+		return;
+	}
+
+	/* Give the GTM buffer + drive Identify data to the channel via the
+	 * _STM method: */
+	/* setup input parameters buffer for _STM */
+	input.count = 3;
+	input.pointer = in_params;
+	in_params[0].type = ACPI_TYPE_BUFFER;
+	in_params[0].buffer.length = sizeof(struct GTM_buffer);
+	in_params[0].buffer.pointer = (u8 *)&hwif->acpidata->gtm;
+	in_params[1].type = ACPI_TYPE_BUFFER;
+	in_params[1].buffer.length = sizeof(struct hd_driveid);
+	in_params[1].buffer.pointer = (u8 *)&master->idbuff;
+	in_params[2].type = ACPI_TYPE_BUFFER;
+	in_params[2].buffer.length = sizeof(struct hd_driveid);
+	in_params[2].buffer.pointer = (u8 *)&slave->idbuff;
+	/* Output buffer: _STM has no output */
+
+	status = acpi_evaluate_object(hwif->acpidata->obj_handle, "_STM",
+				      &input, NULL);
+
+	if (ACPI_FAILURE(status)) {
+		DEBPRINT("Run _STM error: status = 0x%x\n", status);
+	}
+	DEBPRINT("_STM status: %d\n", status);
+}
+EXPORT_SYMBOL_GPL(ide_acpi_push_timing);
+
+/**
+ * ide_acpi_init - initialize the ACPI link for an IDE interface
+ * @hwif: target IDE interface (channel)
+ *
+ * The ACPI spec is not quite clear when the drive identify buffer
+ * should be obtained. Calling IDENTIFY DEVICE during shutdown
+ * is not the best of ideas as the drive might already being put to
+ * sleep. And obviously we can't call it during resume.
+ * So we get the information during startup; but this means that
+ * any changes during run-time will be lost after resume.
+ */
+void ide_acpi_init(ide_hwif_t *hwif)
+{
+	int unit;
+	int			err;
+	struct ide_acpi_drive_link	*master;
+	struct ide_acpi_drive_link	*slave;
+
+	hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL);
+	if (!hwif->acpidata)
+		return;
+
+	hwif->acpidata->obj_handle = ide_acpi_hwif_get_handle(hwif);
+	if (!hwif->acpidata->obj_handle) {
+		DEBPRINT("no ACPI object for %s found\n", hwif->name);
+		kfree(hwif->acpidata);
+		hwif->acpidata = NULL;
+		return;
+	}
+
+	/*
+	 * The ACPI spec mandates that we send information
+	 * for both drives, regardless whether they are connected
+	 * or not.
+	 */
+	hwif->acpidata->master.drive = &hwif->drives[0];
+	hwif->drives[0].acpidata = &hwif->acpidata->master;
+	master = &hwif->acpidata->master;
+
+	hwif->acpidata->slave.drive = &hwif->drives[1];
+	hwif->drives[1].acpidata = &hwif->acpidata->slave;
+	slave = &hwif->acpidata->slave;
+
+
+	/*
+	 * Send IDENTIFY for each drive
+	 */
+	if (master->drive->present) {
+		err = taskfile_lib_get_identify(master->drive, master->idbuff);
+		if (err) {
+			DEBPRINT("identify device %s failed (%d)\n",
+				 master->drive->name, err);
+		}
+	}
+
+	if (slave->drive->present) {
+		err = taskfile_lib_get_identify(slave->drive, slave->idbuff);
+		if (err) {
+			DEBPRINT("identify device %s failed (%d)\n",
+				 slave->drive->name, err);
+		}
+	}
+
+	if (ide_noacpionboot) {
+		DEBPRINT("ACPI methods disabled on boot\n");
+		return;
+	}
+
+	/*
+	 * ACPI requires us to call _STM on startup
+	 */
+	ide_acpi_get_timing(hwif);
+	ide_acpi_push_timing(hwif);
+
+	for (unit = 0; unit < MAX_DRIVES; ++unit) {
+		ide_drive_t *drive = &hwif->drives[unit];
+
+		if (drive->present) {
+			/* Execute ACPI startup code */
+			ide_acpi_exec_tfs(drive);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(ide_acpi_init);
Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1384,6 +1384,9 @@ static int hwif_init(ide_hwif_t *hwif)
 
 done:
 	init_gendisk(hwif);
+
+	ide_acpi_init(hwif);
+
 	hwif->present = 1;	/* success */
 	return 1;
 
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -187,6 +187,12 @@ int noautodma = 1;
 
 EXPORT_SYMBOL(noautodma);
 
+#ifdef CONFIG_BLK_DEV_IDEACPI
+int ide_noacpi = 0;
+int ide_noacpitfs = 1;
+int ide_noacpionboot = 1;
+#endif
+
 /*
  * This is declared extern in ide.h, for access by other IDE modules:
  */
@@ -1211,10 +1217,15 @@ EXPORT_SYMBOL(system_bus_clock);
 static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
 {
 	ide_drive_t *drive = dev->driver_data;
+	ide_hwif_t *hwif = HWIF(drive);
 	struct request rq;
 	struct request_pm_state rqpm;
 	ide_task_t args;
 
+	/* Call ACPI _GTM only once */
+	if (!(drive->dn % 2))
+		ide_acpi_get_timing(hwif);
+
 	memset(&rq, 0, sizeof(rq));
 	memset(&rqpm, 0, sizeof(rqpm));
 	memset(&args, 0, sizeof(args));
@@ -1232,10 +1243,17 @@ static int generic_ide_suspend(struct de
 static int generic_ide_resume(struct device *dev)
 {
 	ide_drive_t *drive = dev->driver_data;
+	ide_hwif_t *hwif = HWIF(drive);
 	struct request rq;
 	struct request_pm_state rqpm;
 	ide_task_t args;
 
+	/* Call ACPI _STM only once */
+	if (!(drive->dn % 2))
+		ide_acpi_push_timing(hwif);
+
+	ide_acpi_exec_tfs(drive);
+
 	memset(&rq, 0, sizeof(rq));
 	memset(&rqpm, 0, sizeof(rqpm));
 	memset(&args, 0, sizeof(args));
@@ -1540,6 +1558,24 @@ static int __init ide_setup(char *s)
 	}
 #endif /* CONFIG_BLK_DEV_IDEPCI */
 
+#ifdef CONFIG_BLK_DEV_IDEACPI
+	if (!strcmp(s, "ide=noacpi")) {
+		//printk(" : Disable IDE ACPI support.\n");
+		ide_noacpi = 1;
+		return 1;
+	}
+	if (!strcmp(s, "ide=acpigtf")) {
+		//printk(" : Enable IDE ACPI _GTF support.\n");
+		ide_noacpitfs = 0;
+		return 1;
+	}
+	if (!strcmp(s, "ide=acpionboot")) {
+		//printk(" : Call IDE ACPI methods on boot.\n");
+		ide_noacpionboot = 0;
+		return 1;
+	}
+#endif /* CONFIG_BLK_DEV_IDEACPI */
+
 	/*
 	 * Look for drive options:  "hdx="
 	 */
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -18,6 +18,9 @@
 #include <linux/device.h>
 #include <linux/pci.h>
 #include <linux/completion.h>
+#ifdef CONFIG_BLK_DEV_IDEACPI
+#include <acpi/acpi.h>
+#endif
 #include <asm/byteorder.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -541,6 +544,11 @@ typedef enum {
 struct ide_driver_s;
 struct ide_settings_s;
 
+#ifdef CONFIG_BLK_DEV_IDEACPI
+struct ide_acpi_drive_link;
+struct ide_acpi_hwif_link;
+#endif
+
 typedef struct ide_drive_s {
 	char		name[4];	/* drive name, such as "hda" */
         char            driver_req[10];	/* requests specific driver */
@@ -636,6 +644,9 @@ typedef struct ide_drive_s {
 
 	int		lun;		/* logical unit */
 	int		crc_count;	/* crc counter to reduce drive speed */
+#ifdef CONFIG_BLK_DEV_IDEACPI
+	struct ide_acpi_drive_link *acpidata;
+#endif
 	struct list_head list;
 	struct device	gendev;
 	struct completion gendev_rel_comp;	/* to deal with device release() */
@@ -800,6 +811,10 @@ typedef struct hwif_s {
 	void		*hwif_data;	/* extra hwif data */
 
 	unsigned dma;
+
+#ifdef CONFIG_BLK_DEV_IDEACPI
+	struct ide_acpi_hwif_link *acpidata;
+#endif
 } ____cacheline_internodealigned_in_smp ide_hwif_t;
 
 /*
@@ -1294,6 +1309,18 @@ static inline void ide_dma_verbose(ide_d
 static inline void ide_release_dma(ide_hwif_t *drive) {;}
 #endif
 
+#ifdef CONFIG_BLK_DEV_IDEACPI
+extern int ide_acpi_exec_tfs(ide_drive_t *drive);
+extern void ide_acpi_get_timing(ide_hwif_t *hwif);
+extern void ide_acpi_push_timing(ide_hwif_t *hwif);
+extern void ide_acpi_init(ide_hwif_t *hwif);
+#else
+static inline int ide_acpi_exec_tfs(ide_drive_t *drive) { return 0; }
+static inline void ide_acpi_get_timing(ide_hwif_t *hwif) { ; }
+static inline void ide_acpi_push_timing(ide_hwif_t *hwif) { ; }
+static inline void ide_acpi_init(ide_hwif_t *hwif) { ; }
+#endif
+
 extern int ide_hwif_request_regions(ide_hwif_t *hwif);
 extern void ide_hwif_release_regions(ide_hwif_t* hwif);
 extern void ide_unregister (unsigned int index);

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

* [PATCH 2/15] via82cxxx/pata_via: correct PCI_DEVICE_ID_VIA_SATA_EIDE ID and add support for CX700 and 8237S
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
  2007-01-19  0:31 ` [PATCH 1/15] ACPI support for IDE devices Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:31 ` Bartlomiej Zolnierkiewicz
  2007-01-19  0:31 ` [PATCH 3/15] it8213: fix build and ->ultra_mask Bartlomiej Zolnierkiewicz
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:31 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] via82cxxx/pata_via: correct PCI_DEVICE_ID_VIA_SATA_EIDE ID and add support for CX700 and 8237S

This patch:
* Corrects the wrong device ID of PCI_DEVICE_ID_VIA_SATA_EIDE
  from 0x0581 to 0x5324.
* Adds VIA CX700 and VT8237S support in drivers/ide/pci/via82cxxx.c
* Adds VIA VT8237S support in drivers/ata/pata_via.c

Signed-off-by: Josepch Chan <josephchan@via.com.tw>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ata/pata_via.c      |    1 +
 drivers/ide/pci/via82cxxx.c |    3 +++
 include/linux/pci_ids.h     |    3 ++-
 3 files changed, 6 insertions(+), 1 deletion(-)

Index: b/drivers/ata/pata_via.c
===================================================================
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -95,6 +95,7 @@ static const struct via_isa_bridge {
 	u8 rev_max;
 	u16 flags;
 } via_isa_bridges[] = {
+	{ "vt8237s",	PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8251",	PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "cx700",	PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt6410",	PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES},
Index: b/drivers/ide/pci/via82cxxx.c
===================================================================
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -78,6 +78,8 @@ static struct via_isa_bridge {
 	u8 rev_max;
 	u16 flags;
 } via_isa_bridges[] = {
+	{ "cx7000",	PCI_DEVICE_ID_VIA_CX700,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+	{ "vt8237s",	PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt6410",	PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8251",	PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
@@ -504,6 +506,7 @@ static struct pci_device_id via_pci_tbl[
 	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_SATA_EIDE,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, via_pci_tbl);
Index: b/include/linux/pci_ids.h
===================================================================
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1283,7 +1283,6 @@
 #define PCI_DEVICE_ID_VIA_82C561	0x0561
 #define PCI_DEVICE_ID_VIA_82C586_1	0x0571
 #define PCI_DEVICE_ID_VIA_82C576	0x0576
-#define PCI_DEVICE_ID_VIA_SATA_EIDE	0x0581
 #define PCI_DEVICE_ID_VIA_82C586_0	0x0586
 #define PCI_DEVICE_ID_VIA_82C596	0x0596
 #define PCI_DEVICE_ID_VIA_82C597_0	0x0597
@@ -1326,6 +1325,8 @@
 #define PCI_DEVICE_ID_VIA_8237		0x3227
 #define PCI_DEVICE_ID_VIA_8251		0x3287
 #define PCI_DEVICE_ID_VIA_8237A		0x3337
+#define PCI_DEVICE_ID_VIA_8237S		0x3372
+#define PCI_DEVICE_ID_VIA_SATA_EIDE	0x5324
 #define PCI_DEVICE_ID_VIA_8231		0x8231
 #define PCI_DEVICE_ID_VIA_8231_4	0x8235
 #define PCI_DEVICE_ID_VIA_8365_1	0x8305

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

* [PATCH 3/15] it8213: fix build and ->ultra_mask
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
  2007-01-19  0:31 ` [PATCH 1/15] ACPI support for IDE devices Bartlomiej Zolnierkiewicz
  2007-01-19  0:31 ` [PATCH 2/15] via82cxxx/pata_via: correct PCI_DEVICE_ID_VIA_SATA_EIDE ID and add support for CX700 and 8237S Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:31 ` Bartlomiej Zolnierkiewicz
  2007-01-19  0:31 ` [PATCH 4/15] ide: convert ide_hwif_t.mmio into flag Bartlomiej Zolnierkiewicz
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:31 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] it8213: fix build and ->ultra_mask

* PCI_DEVICE_ID_ITE_8213 is only defined in -mm kernels,
  so just use PCI Device ID (0x8213) directly
* fix ->ultra_mask to indicate UDMA6 support

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/pci/it8213.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: b/drivers/ide/pci/it8213.c
===================================================================
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -282,7 +282,7 @@ static void __devinit init_hwif_it8213(i
 		return;
 
 	hwif->atapi_dma = 1;
-	hwif->ultra_mask = 0x3f;
+	hwif->ultra_mask = 0x7f;
 	hwif->mwdma_mask = 0x06;
 	hwif->swdma_mask = 0x04;
 
@@ -338,7 +338,7 @@ static int __devinit it8213_init_one(str
 
 
 static struct pci_device_id it8213_pci_tbl[] = {
-	{ PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8213,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ITE, 0x8213, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ 0, },
 };
 

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

* [PATCH 4/15] ide: convert ide_hwif_t.mmio into flag
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (2 preceding siblings ...)
  2007-01-19  0:31 ` [PATCH 3/15] it8213: fix build and ->ultra_mask Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:31 ` Bartlomiej Zolnierkiewicz
  2007-01-19  0:31 ` [PATCH 5/15] hpt34x: hpt34x_tune_chipset() (->speedproc) fix Bartlomiej Zolnierkiewicz
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:31 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] ide: convert ide_hwif_t.mmio into flag

All users of ->mmio == 1 are gone so convert ->mmio into flag.

Noticed by Alan Cox.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/arm/icside.c      |    2 +-
 drivers/ide/arm/rapide.c      |    2 +-
 drivers/ide/cris/ide-cris.c   |    2 +-
 drivers/ide/h8300/ide-h8300.c |    2 +-
 drivers/ide/ide-dma.c         |    8 ++++----
 drivers/ide/ide.c             |    5 ++---
 drivers/ide/legacy/buddha.c   |    2 +-
 drivers/ide/legacy/gayle.c    |    2 +-
 drivers/ide/legacy/macide.c   |    2 +-
 drivers/ide/legacy/q40ide.c   |    2 +-
 drivers/ide/mips/au1xxx-ide.c |    3 ++-
 drivers/ide/mips/swarm.c      |    2 +-
 drivers/ide/pci/sgiioc4.c     |    2 +-
 drivers/ide/pci/siimage.c     |    3 ++-
 drivers/ide/ppc/pmac.c        |    2 +-
 include/linux/ide.h           |    2 +-
 16 files changed, 22 insertions(+), 21 deletions(-)

Index: b/drivers/ide/arm/icside.c
===================================================================
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -556,7 +556,7 @@ icside_setup(void __iomem *base, struct 
 		 * Ensure we're using MMIO
 		 */
 		default_hwif_mmiops(hwif);
-		hwif->mmio = 2;
+		hwif->mmio = 1;
 
 		for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
 			hwif->hw.io_ports[i] = port;
Index: b/drivers/ide/arm/rapide.c
===================================================================
--- a/drivers/ide/arm/rapide.c
+++ b/drivers/ide/arm/rapide.c
@@ -46,7 +46,7 @@ rapide_locate_hwif(void __iomem *base, v
 	hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
 	hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
 	hwif->hw.irq = hwif->irq = irq;
-	hwif->mmio = 2;
+	hwif->mmio = 1;
 	default_hwif_mmiops(hwif);
 
 	return hwif;
Index: b/drivers/ide/cris/ide-cris.c
===================================================================
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -795,7 +795,7 @@ init_e100_ide (void)
 		                0, 0, cris_ide_ack_intr,
 		                ide_default_irq(0));
 		ide_register_hw(&hw, &hwif);
-		hwif->mmio = 2;
+		hwif->mmio = 1;
 		hwif->chipset = ide_etrax100;
 		hwif->tuneproc = &tune_cris_ide;
 		hwif->speedproc = &speed_cris_ide;
Index: b/drivers/ide/h8300/ide-h8300.c
===================================================================
--- a/drivers/ide/h8300/ide-h8300.c
+++ b/drivers/ide/h8300/ide-h8300.c
@@ -76,7 +76,7 @@ static inline void hwif_setup(ide_hwif_t
 {
 	default_hwif_iops(hwif);
 
-	hwif->mmio  = 2;
+	hwif->mmio  = 1;
 	hwif->OUTW  = mm_outw;
 	hwif->OUTSW = mm_outsw;
 	hwif->INW   = mm_inw;
Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -565,7 +565,7 @@ int ide_dma_setup(ide_drive_t *drive)
 	}
 
 	/* PRD table */
-	if (hwif->mmio == 2)
+	if (hwif->mmio)
 		writel(hwif->dmatable_dma, (void __iomem *)hwif->dma_prdtable);
 	else
 		outl(hwif->dmatable_dma, hwif->dma_prdtable);
@@ -815,7 +815,7 @@ int ide_release_dma(ide_hwif_t *hwif)
 {
 	ide_release_dma_engine(hwif);
 
-	if (hwif->mmio == 2)
+	if (hwif->mmio)
 		return 1;
 	else
 		return ide_release_iomio_dma(hwif);
@@ -884,9 +884,9 @@ static int ide_iomio_dma(ide_hwif_t *hwi
 
 static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int ports)
 {
-	if (hwif->mmio == 2)
+	if (hwif->mmio)
 		return ide_mapped_mmio_dma(hwif, base,ports);
-	BUG_ON(hwif->mmio == 1);
+
 	return ide_iomio_dma(hwif, base, ports);
 }
 
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -389,9 +389,8 @@ int ide_hwif_request_regions(ide_hwif_t 
 	unsigned long addr;
 	unsigned int i;
 
-	if (hwif->mmio == 2)
+	if (hwif->mmio)
 		return 0;
-	BUG_ON(hwif->mmio == 1);
 	addr = hwif->io_ports[IDE_CONTROL_OFFSET];
 	if (addr && !hwif_request_region(hwif, addr, 1))
 		goto control_region_busy;
@@ -438,7 +437,7 @@ void ide_hwif_release_regions(ide_hwif_t
 {
 	u32 i = 0;
 
-	if (hwif->mmio == 2)
+	if (hwif->mmio)
 		return;
 	if (hwif->io_ports[IDE_CONTROL_OFFSET])
 		release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
Index: b/drivers/ide/legacy/buddha.c
===================================================================
--- a/drivers/ide/legacy/buddha.c
+++ b/drivers/ide/legacy/buddha.c
@@ -215,7 +215,7 @@ fail_base2:
 			
 			index = ide_register_hw(&hw, &hwif);
 			if (index != -1) {
-				hwif->mmio = 2;
+				hwif->mmio = 1;
 				printk("ide%d: ", index);
 				switch(type) {
 				case BOARD_BUDDHA:
Index: b/drivers/ide/legacy/gayle.c
===================================================================
--- a/drivers/ide/legacy/gayle.c
+++ b/drivers/ide/legacy/gayle.c
@@ -167,7 +167,7 @@ found:
 
 	index = ide_register_hw(&hw, &hwif);
 	if (index != -1) {
-	    hwif->mmio = 2;
+	    hwif->mmio = 1;
 	    switch (i) {
 		case 0:
 		    printk("ide%d: Gayle IDE interface (A%d style)\n", index,
Index: b/drivers/ide/legacy/macide.c
===================================================================
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -141,7 +141,7 @@ void macide_init(void)
 	}
 
         if (index != -1) {
-		hwif->mmio = 2;
+		hwif->mmio = 1;
 		if (macintosh_config->ide_type == MAC_IDE_QUADRA)
 			printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index);
 		else if (macintosh_config->ide_type == MAC_IDE_PB)
Index: b/drivers/ide/legacy/q40ide.c
===================================================================
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -145,7 +145,7 @@ void q40ide_init(void)
 	index = ide_register_hw(&hw, &hwif);
 	// **FIXME**
 	if (index != -1)
-		hwif->mmio = 2;
+		hwif->mmio = 1;
     }
 }
 
Index: b/drivers/ide/mips/au1xxx-ide.c
===================================================================
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -708,7 +708,8 @@ static int au_ide_probe(struct device *d
 
 	/* hold should be on in all cases */
 	hwif->hold                      = 1;
-	hwif->mmio                      = 2;
+
+	hwif->mmio  = 1;
 
 	/* If the user has selected DDMA assisted copies,
 	   then set up a few local I/O function entry points 
Index: b/drivers/ide/mips/swarm.c
===================================================================
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -115,7 +115,7 @@ static int __devinit swarm_ide_probe(str
 	/* Setup MMIO ops.  */
 	default_hwif_mmiops(hwif);
 	/* Prevent resource map manipulation.  */
-	hwif->mmio = 2;
+	hwif->mmio = 1;
 	hwif->noprobe = 0;
 
 	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
Index: b/drivers/ide/pci/sgiioc4.c
===================================================================
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -593,7 +593,7 @@ static int sgiioc4_ide_dma_setup(ide_dri
 static void __devinit
 ide_init_sgiioc4(ide_hwif_t * hwif)
 {
-	hwif->mmio = 2;
+	hwif->mmio = 1;
 	hwif->autodma = 1;
 	hwif->atapi_dma = 1;
 	hwif->ultra_mask = 0x0;	/* Disable Ultra DMA */
Index: b/drivers/ide/pci/siimage.c
===================================================================
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -889,7 +889,8 @@ static void __devinit init_mmio_iops_sii
        	base = (unsigned long) addr;
 
 	hwif->dma_base			= base + (ch ? 0x08 : 0x00);
-	hwif->mmio			= 2;
+
+	hwif->mmio = 1;
 }
 
 static int is_dev_seagate_sata(ide_drive_t *drive)
Index: b/drivers/ide/ppc/pmac.c
===================================================================
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1238,7 +1238,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p
        	hwif->OUTBSYNC = pmac_outbsync;
 
 	/* Tell common code _not_ to mess with resources */
-	hwif->mmio = 2;
+	hwif->mmio = 1;
 	hwif->hwif_data = pmif;
 	pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq);
 	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -771,7 +771,6 @@ typedef struct hwif_s {
 	unsigned int cursg;
 	unsigned int cursg_ofs;
 
-	int		mmio;		/* hosts iomio (0) or custom (2) select */
 	int		rqsize;		/* max sectors per request */
 	int		irq;		/* our irq number */
 
@@ -804,6 +803,7 @@ typedef struct hwif_s {
 	unsigned	no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */
 	unsigned	err_stops_fifo : 1; /* 1=data FIFO is cleared by an error */
 	unsigned	atapi_irq_bogon : 1; /* Generates spurious DMA interrupts in PIO mode */
+	unsigned	mmio       : 1; /* host uses MMIO */
 
 	struct device	gendev;
 	struct completion gendev_rel_comp; /* To deal with device release() */

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

* [PATCH 5/15] hpt34x: hpt34x_tune_chipset() (->speedproc) fix
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (3 preceding siblings ...)
  2007-01-19  0:31 ` [PATCH 4/15] ide: convert ide_hwif_t.mmio into flag Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:31 ` Bartlomiej Zolnierkiewicz
  2007-01-19  0:31 ` [PATCH 6/15] atiixp/jmicron/triflex: fix PIO fallback Bartlomiej Zolnierkiewicz
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:31 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] hpt34x: hpt34x_tune_chipset() (->speedproc) fix

* remember to clear reg2 bits for the current device before setting mode
* remove no longer needed hpt34x_clear_chipset()

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/pci/hpt34x.c |   17 +----------------
 1 file changed, 1 insertion(+), 16 deletions(-)

Index: b/drivers/ide/pci/hpt34x.c
===================================================================
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -48,19 +48,6 @@ static u8 hpt34x_ratemask (ide_drive_t *
 	return 1;
 }
 
-static void hpt34x_clear_chipset (ide_drive_t *drive)
-{
-	struct pci_dev *dev	= HWIF(drive)->pci_dev;
-	u32 reg1 = 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
-
-	pci_read_config_dword(dev, 0x44, &reg1);
-	pci_read_config_dword(dev, 0x48, &reg2);
-	tmp1 = ((0x00 << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
-	tmp2 = (reg2 & ~(0x11 << drive->dn));
-	pci_write_config_dword(dev, 0x44, tmp1);
-	pci_write_config_dword(dev, 0x48, tmp2);
-}
-
 static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
 {
 	struct pci_dev *dev	= HWIF(drive)->pci_dev;
@@ -81,7 +68,7 @@ static int hpt34x_tune_chipset (ide_driv
 	pci_read_config_dword(dev, 0x44, &reg1);
 	pci_read_config_dword(dev, 0x48, &reg2);
 	tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
-	tmp2 = ((hi_speed << drive->dn) | reg2);
+	tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn)));
 	pci_write_config_dword(dev, 0x44, tmp1);
 	pci_write_config_dword(dev, 0x48, tmp2);
 
@@ -99,7 +86,6 @@ static int hpt34x_tune_chipset (ide_driv
 static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio)
 {
 	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
-	hpt34x_clear_chipset(drive);
 	(void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio));
 }
 
@@ -117,7 +103,6 @@ static int config_chipset_for_dma (ide_d
 	if (!(speed))
 		return 0;
 
-	hpt34x_clear_chipset(drive);
 	(void) hpt34x_tune_chipset(drive, speed);
 	return ide_dma_enable(drive);
 }

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

* [PATCH 6/15] atiixp/jmicron/triflex: fix PIO fallback
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (4 preceding siblings ...)
  2007-01-19  0:31 ` [PATCH 5/15] hpt34x: hpt34x_tune_chipset() (->speedproc) fix Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:31 ` Bartlomiej Zolnierkiewicz
  2007-01-19  0:31 ` [PATCH 7/15] piix: cleanup Bartlomiej Zolnierkiewicz
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:31 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] atiixp/jmicron/triflex: fix PIO fallback

* atiixp: if DMA can't be used atiixp_config_drive_for_dma() should return 0,
  atiixp_dma_check() will tune the correct PIO mode anyway

* jmicron: if DMA can't be used config_chipset_for_dma() should return 0,
  micron_config_drive_for_dma() will tune the correct PIO mode anyway

  config_jmicron_chipset_for_pio(drive, !speed) doesn't program
  device transfer mode for speed != 0 (only wastes some CPU cycles
  on ide_get_best_pio_mode() call) so remove it

* triflex: if DMA can't be used triflex_config_drive_for_dma() should return 0,
  triflex_config_drive_xfer_rate() will tune correct PIO mode anyway

Above changes also fix (theoretical) issue when ->speedproc fails to set
device transfer mode (i.e. when ide_config_drive_speed() fails to program it)
but one of DMA transfer modes is already enabled on the device by the BIOS.
In such scenario ide_dma_enable() will incorrectly return true statement
and ->ide_dma_check will try to enable DMA on the device.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/pci/atiixp.c  |    7 ++-----
 drivers/ide/pci/jmicron.c |    4 +++-
 drivers/ide/pci/triflex.c |    8 +++-----
 3 files changed, 8 insertions(+), 11 deletions(-)

Index: b/drivers/ide/pci/atiixp.c
===================================================================
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -235,11 +235,8 @@ static int atiixp_config_drive_for_dma(i
 {
 	u8 speed = ide_dma_speed(drive, atiixp_ratemask(drive));
 
-	/* If no DMA speed was available then disable DMA and use PIO. */
-	if (!speed) {
-		u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
-		speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
-	}
+	if (!speed)
+		return 0;
 
 	(void) atiixp_speedproc(drive, speed);
 	return ide_dma_enable(drive);
Index: b/drivers/ide/pci/jmicron.c
===================================================================
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -147,7 +147,9 @@ static int config_chipset_for_dma (ide_d
 {
 	u8 speed	= ide_dma_speed(drive, jmicron_ratemask(drive));
 
-	config_jmicron_chipset_for_pio(drive, !speed);
+	if (!speed)
+		return 0;
+
 	jmicron_tune_chipset(drive, speed);
 	return ide_dma_enable(drive);
 }
Index: b/drivers/ide/pci/triflex.c
===================================================================
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -104,11 +104,9 @@ static int triflex_config_drive_for_dma(
 {
 	int speed = ide_dma_speed(drive, 0); /* No ultra speeds */
 
-	if (!speed) { 
-		u8 pspeed = ide_get_best_pio_mode(drive, 255, 4, NULL);
-		speed = XFER_PIO_0 + pspeed;
-	}
-	
+	if (!speed)
+		return 0;
+
 	(void) triflex_tune_chipset(drive, speed);
 	 return ide_dma_enable(drive);
 }

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

* [PATCH 7/15] piix: cleanup
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (5 preceding siblings ...)
  2007-01-19  0:31 ` [PATCH 6/15] atiixp/jmicron/triflex: fix PIO fallback Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:31 ` Bartlomiej Zolnierkiewicz
  2007-01-19  0:31 ` [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case Bartlomiej Zolnierkiewicz
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:31 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] piix: cleanup

* disable DMA masks if no_piix_dma is set and remove now
  not needed no_piix_dma_check from piix_config_drive_for_dma()
* there is no need to read register 0x55 in init_hwif_piix()
* move cable detection code to piix_cable_detect()
* remove unreachable 82371MX code from init_hwif_piix()

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/pci/piix.c |   28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

Index: b/drivers/ide/pci/piix.c
===================================================================
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -369,7 +369,7 @@ static int piix_config_drive_for_dma (id
 	 * If no DMA speed was available or the chipset has DMA bugs
 	 * then disable DMA and use PIO
 	 */
-	if (!speed || no_piix_dma)
+	if (!speed)
 		return 0;
 
 	(void) piix_tune_chipset(drive, speed);
@@ -444,6 +444,16 @@ static unsigned int __devinit init_chips
 	return 0;
 }
 
+static int __devinit piix_cable_detect(ide_hwif_t *hwif)
+{
+	struct pci_dev *dev = hwif->pci_dev;
+	u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30;
+
+	pci_read_config_byte(dev, 0x54, &reg54h);
+
+	return (reg54h & mask) ? 1 : 0;
+}
+
 /**
  *	init_hwif_piix		-	fill in the hwif for the PIIX
  *	@hwif: IDE interface
@@ -454,9 +464,6 @@ static unsigned int __devinit init_chips
 
 static void __devinit init_hwif_piix(ide_hwif_t *hwif)
 {
-	u8 reg54h = 0, reg55h = 0, ata66 = 0;
-	u8 mask = hwif->channel ? 0xc0 : 0x30;
-
 #ifndef CONFIG_IA64
 	if (!hwif->irq)
 		hwif->irq = hwif->channel ? 15 : 14;
@@ -486,9 +493,6 @@ static void __devinit init_hwif_piix(ide
 	hwif->swdma_mask = 0x04;
 
 	switch(hwif->pci_dev->device) {
-		case PCI_DEVICE_ID_INTEL_82371MX:
-			hwif->mwdma_mask = 0x80;
-			hwif->swdma_mask = 0x80;
 		case PCI_DEVICE_ID_INTEL_82371FB_0:
 		case PCI_DEVICE_ID_INTEL_82371FB_1:
 		case PCI_DEVICE_ID_INTEL_82371SB_1:
@@ -501,14 +505,14 @@ static void __devinit init_hwif_piix(ide
 			hwif->ultra_mask = 0x07;
 			break;
 		default:
-			pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h);
-			pci_read_config_byte(hwif->pci_dev, 0x55, &reg55h);
-			ata66 = (reg54h & mask) ? 1 : 0;
+			if (!hwif->udma_four)
+				hwif->udma_four = piix_cable_detect(hwif);
 			break;
 	}
 
-	if (!(hwif->udma_four))
-		hwif->udma_four = ata66;
+	if (no_piix_dma)
+		hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0;
+
 	hwif->ide_dma_check = &piix_config_drive_xfer_rate;
 	if (!noautodma)
 		hwif->autodma = 1;

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

* [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (6 preceding siblings ...)
  2007-01-19  0:31 ` [PATCH 7/15] piix: cleanup Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:31 ` Bartlomiej Zolnierkiewicz
  2007-01-19 16:26   ` Sergei Shtylyov
  2007-01-19  0:32 ` [PATCH 9/15] sgiioc4: fix sgiioc4_ide_dma_check() to enable/disable DMA properly Bartlomiej Zolnierkiewicz
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:31 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] ide: disable DMA in ->ide_dma_check for "no IORDY" case

If DMA is unsupported ->ide_dma_check should disable DMA.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/pci/aec62xx.c      |    8 +++-----
 drivers/ide/pci/atiixp.c       |    5 ++---
 drivers/ide/pci/cmd64x.c       |    8 +++-----
 drivers/ide/pci/cs5535.c       |    5 ++---
 drivers/ide/pci/hpt34x.c       |    8 +++-----
 drivers/ide/pci/hpt366.c       |    8 +++-----
 drivers/ide/pci/pdc202xx_new.c |    8 +++-----
 drivers/ide/pci/pdc202xx_old.c |    8 +++-----
 drivers/ide/pci/piix.c         |    5 ++---
 drivers/ide/pci/serverworks.c  |    9 +++------
 drivers/ide/pci/siimage.c      |    8 +++-----
 drivers/ide/pci/sis5513.c      |    8 +++-----
 drivers/ide/pci/slc90e66.c     |    5 ++---
 drivers/ide/pci/tc86c001.c     |    8 +++-----
 14 files changed, 38 insertions(+), 63 deletions(-)

Index: b/drivers/ide/pci/aec62xx.c
===================================================================
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -214,12 +214,10 @@ static int aec62xx_config_drive_xfer_rat
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
 		return hwif->ide_dma_on(drive);
 
-	if (ide_use_fast_pio(drive)) {
+	if (ide_use_fast_pio(drive))
 		aec62xx_tune_drive(drive, 5);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 static int aec62xx_irq_timeout (ide_drive_t *drive)
Index: b/drivers/ide/pci/atiixp.c
===================================================================
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -264,10 +264,9 @@ static int atiixp_dma_check(ide_drive_t 
 		tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
 		speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
 		hwif->speedproc(drive, speed);
-		return hwif->ide_dma_off_quietly(drive);
 	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 /**
Index: b/drivers/ide/pci/cmd64x.c
===================================================================
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -479,12 +479,10 @@ static int cmd64x_config_drive_for_dma (
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
 		return hwif->ide_dma_on(drive);
 
-	if (ide_use_fast_pio(drive)) {
+	if (ide_use_fast_pio(drive))
 		config_chipset_for_pio(drive, 1);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 static int cmd64x_alt_dma_status (struct pci_dev *dev)
Index: b/drivers/ide/pci/cs5535.c
===================================================================
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -206,10 +206,9 @@ static int cs5535_dma_check(ide_drive_t 
 	if (ide_use_fast_pio(drive)) {
 		speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
 		cs5535_set_drive(drive, speed);
-		return hwif->ide_dma_off_quietly(drive);
 	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
Index: b/drivers/ide/pci/hpt34x.c
===================================================================
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -120,12 +120,10 @@ static int hpt34x_config_drive_xfer_rate
 		return hwif->ide_dma_on(drive);
 #endif
 
-	if (ide_use_fast_pio(drive)) {
+	if (ide_use_fast_pio(drive))
 		hpt34x_tune_drive(drive, 255);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 /*
Index: b/drivers/ide/pci/hpt366.c
===================================================================
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -743,12 +743,10 @@ static int hpt366_config_drive_xfer_rate
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
 		return hwif->ide_dma_on(drive);
 
-	if (ide_use_fast_pio(drive)) {
+	if (ide_use_fast_pio(drive))
 		hpt3xx_tune_drive(drive, 255);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 /*
Index: b/drivers/ide/pci/pdc202xx_new.c
===================================================================
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -288,12 +288,10 @@ static int pdcnew_config_drive_xfer_rate
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
 		return hwif->ide_dma_on(drive);
 
-	if (ide_use_fast_pio(drive)) {
+	if (ide_use_fast_pio(drive))
 		hwif->tuneproc(drive, 255);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 static int pdcnew_quirkproc(ide_drive_t *drive)
Index: b/drivers/ide/pci/pdc202xx_old.c
===================================================================
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -339,12 +339,10 @@ static int pdc202xx_config_drive_xfer_ra
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
 		return hwif->ide_dma_on(drive);
 
-	if (ide_use_fast_pio(drive)) {
+	if (ide_use_fast_pio(drive))
 		hwif->tuneproc(drive, 5);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 static int pdc202xx_quirkproc (ide_drive_t *drive)
Index: b/drivers/ide/pci/piix.c
===================================================================
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -397,10 +397,9 @@ static int piix_config_drive_xfer_rate (
 		/* Find best PIO mode. */
 		(void) hwif->speedproc(drive, XFER_PIO_0 +
 				       ide_get_best_pio_mode(drive, 255, 4, NULL));
-		return hwif->ide_dma_off_quietly(drive);
 	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 /**
Index: b/drivers/ide/pci/serverworks.c
===================================================================
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -322,13 +322,10 @@ static int svwks_config_drive_xfer_rate 
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
 		return hwif->ide_dma_on(drive);
 
-	if (ide_use_fast_pio(drive)) {
+	if (ide_use_fast_pio(drive))
 		config_chipset_for_pio(drive);
-		//	hwif->tuneproc(drive, 5);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const char *name)
Index: b/drivers/ide/pci/siimage.c
===================================================================
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -420,12 +420,10 @@ static int siimage_config_drive_for_dma 
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
 		return hwif->ide_dma_on(drive);
 
-	if (ide_use_fast_pio(drive)) {
+	if (ide_use_fast_pio(drive))
 		config_chipset_for_pio(drive, 1);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 /* returns 1 if dma irq issued, 0 otherwise */
Index: b/drivers/ide/pci/sis5513.c
===================================================================
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -678,12 +678,10 @@ static int sis5513_config_xfer_rate(ide_
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
 		return hwif->ide_dma_on(drive);
 
-	if (ide_use_fast_pio(drive)) {
+	if (ide_use_fast_pio(drive))
 		sis5513_tune_drive(drive, 5);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 /* Chip detection and general config */
Index: b/drivers/ide/pci/slc90e66.c
===================================================================
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -189,10 +189,9 @@ static int slc90e66_config_drive_xfer_ra
 	if (ide_use_fast_pio(drive)) {
 		(void) hwif->speedproc(drive, XFER_PIO_0 +
 				       ide_get_best_pio_mode(drive, 255, 4, NULL));
-		return hwif->ide_dma_off_quietly(drive);
 	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
Index: b/drivers/ide/pci/tc86c001.c
===================================================================
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -190,12 +190,10 @@ static int tc86c001_config_drive_xfer_ra
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
 		return hwif->ide_dma_on(drive);
 
-	if (ide_use_fast_pio(drive)) {
+	if (ide_use_fast_pio(drive))
 		tc86c001_tune_drive(drive, 255);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)

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

* [PATCH 9/15] sgiioc4: fix sgiioc4_ide_dma_check() to enable/disable DMA properly
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (7 preceding siblings ...)
  2007-01-19  0:31 ` [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:32 ` Bartlomiej Zolnierkiewicz
  2007-01-19  0:32 ` [PATCH 10/15] ide: add ide_set_dma() helper Bartlomiej Zolnierkiewicz
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:32 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] sgiioc4: fix sgiioc4_ide_dma_check() to enable/disable DMA properly

* use sgiioc4_ide_dma_{on,off_quietly}() instead of changing
  drive->using_dma directly
* fix warning message
* add FIXME

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/pci/sgiioc4.c |   26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)

Index: b/drivers/ide/pci/sgiioc4.c
===================================================================
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -275,21 +275,6 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
 }
 
 static int
-sgiioc4_ide_dma_check(ide_drive_t * drive)
-{
-	if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
-		printk(KERN_INFO
-		       "Couldnot set %s in Multimode-2 DMA mode | "
-			   "Drive %s using PIO instead\n",
-		       drive->name, drive->name);
-		drive->using_dma = 0;
-	} else
-		drive->using_dma = 1;
-
-	return 0;
-}
-
-static int
 sgiioc4_ide_dma_on(ide_drive_t * drive)
 {
 	drive->using_dma = 1;
@@ -305,6 +290,17 @@ sgiioc4_ide_dma_off_quietly(ide_drive_t 
 	return HWIF(drive)->ide_dma_host_off(drive);
 }
 
+static int sgiioc4_ide_dma_check(ide_drive_t *drive)
+{
+	/* FIXME: check for available DMA modes */
+	if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
+		printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, "
+				    "using PIO instead\n", drive->name);
+		return sgiioc4_ide_dma_off_quietly(drive);
+	} else
+		return sgiioc4_ide_dma_on(drive);
+}
+
 /* returns 1 if dma irq issued, 0 otherwise */
 static int
 sgiioc4_ide_dma_test_irq(ide_drive_t * drive)

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

* [PATCH 10/15] ide: add ide_set_dma() helper
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (8 preceding siblings ...)
  2007-01-19  0:32 ` [PATCH 9/15] sgiioc4: fix sgiioc4_ide_dma_check() to enable/disable DMA properly Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:32 ` Bartlomiej Zolnierkiewicz
  2007-01-20 20:22   ` Sergei Shtylyov
  2007-01-19  0:32 ` [PATCH 11/15] ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void Bartlomiej Zolnierkiewicz
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:32 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] ide: add ide_set_dma() helper

* add ide_set_dma() helper and make ide_hwif_t.ide_dma_check return
  -1 when DMA needs to be disabled (== need to call ->ide_dma_off_quietly)
   0 when DMA needs to be enabled  (== need to call ->ide_dma_on)
   1 when DMA setting shouldn't be changed
* fix IDE code to use ide_set_dma() instead if using ->ide_dma_check directly

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/arm/icside.c       |    5 +----
 drivers/ide/cris/ide-cris.c    |    6 ++----
 drivers/ide/ide-dma.c          |   37 ++++++++++++++++++++++++++++++-------
 drivers/ide/ide-io.c           |    2 +-
 drivers/ide/ide-probe.c        |    2 +-
 drivers/ide/ide.c              |    3 ++-
 drivers/ide/mips/au1xxx-ide.c  |    4 ++--
 drivers/ide/pci/aec62xx.c      |    6 ++----
 drivers/ide/pci/alim15x3.c     |   11 +++++------
 drivers/ide/pci/amd74xx.c      |    5 +++--
 drivers/ide/pci/atiixp.c       |    7 +++----
 drivers/ide/pci/cmd64x.c       |    6 ++----
 drivers/ide/pci/cs5520.c       |    5 ++---
 drivers/ide/pci/cs5530.c       |    5 +----
 drivers/ide/pci/cs5535.c       |    5 ++---
 drivers/ide/pci/hpt34x.c       |    8 +++-----
 drivers/ide/pci/hpt366.c       |    6 ++----
 drivers/ide/pci/it8213.c       |   14 ++++++--------
 drivers/ide/pci/it821x.c       |   12 +++++-------
 drivers/ide/pci/jmicron.c      |   10 ++++------
 drivers/ide/pci/ns87415.c      |    3 ++-
 drivers/ide/pci/pdc202xx_new.c |    8 +++-----
 drivers/ide/pci/pdc202xx_old.c |    8 +++-----
 drivers/ide/pci/piix.c         |   10 ++++------
 drivers/ide/pci/sc1200.c       |    5 +----
 drivers/ide/pci/serverworks.c  |    6 ++----
 drivers/ide/pci/sgiioc4.c      |    4 ++--
 drivers/ide/pci/siimage.c      |    6 ++----
 drivers/ide/pci/sis5513.c      |    6 ++----
 drivers/ide/pci/sl82c105.c     |    6 +++---
 drivers/ide/pci/slc90e66.c     |   10 ++++------
 drivers/ide/pci/tc86c001.c     |    6 ++----
 drivers/ide/pci/triflex.c      |    9 ++++-----
 drivers/ide/pci/via82cxxx.c    |    5 +++--
 include/linux/ide.h            |    2 ++
 35 files changed, 118 insertions(+), 135 deletions(-)

Index: b/drivers/ide/arm/icside.c
===================================================================
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -365,10 +365,7 @@ static int icside_dma_check(ide_drive_t 
 out:
 	on = icside_set_speed(drive, xfer_mode);
 
-	if (on)
-		return icside_dma_on(drive);
-	else
-		return icside_dma_off_quietly(drive);
+	return on ? 0 : -1;
 }
 
 static int icside_dma_end(ide_drive_t *drive)
Index: b/drivers/ide/cris/ide-cris.c
===================================================================
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -1048,12 +1048,10 @@ static ide_startstop_t cris_dma_intr (id
 
 static int cris_dma_check(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
-
 	if (ide_use_dma(drive) && cris_config_drive_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static int cris_dma_end(ide_drive_t *drive)
Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -348,15 +348,14 @@ EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
 static int config_drive_for_dma (ide_drive_t *drive)
 {
 	struct hd_driveid *id = drive->id;
-	ide_hwif_t *hwif = HWIF(drive);
 
-	if ((id->capability & 1) && hwif->autodma) {
+	if ((id->capability & 1) && drive->hwif->autodma) {
 		/*
 		 * Enable DMA on any drive that has
 		 * UltraDMA (mode 0/1/2/3/4/5/6) enabled
 		 */
 		if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f))
-			return hwif->ide_dma_on(drive);
+			return 0;
 		/*
 		 * Enable DMA on any drive that has mode2 DMA
 		 * (multi or single) enabled
@@ -364,14 +363,14 @@ static int config_drive_for_dma (ide_dri
 		if (id->field_valid & 2)	/* regular DMA */
 			if ((id->dma_mword & 0x404) == 0x404 ||
 			    (id->dma_1word & 0x404) == 0x404)
-				return hwif->ide_dma_on(drive);
+				return 0;
 
 		/* Consult the list of known "good" drives */
 		if (__ide_dma_good_drive(drive))
-			return hwif->ide_dma_on(drive);
+			return 0;
 	}
-//	if (hwif->tuneproc != NULL) hwif->tuneproc(drive, 255);
-	return hwif->ide_dma_off_quietly(drive);
+
+	return -1;
 }
 
 /**
@@ -765,6 +764,30 @@ bug_dma_off:
 
 EXPORT_SYMBOL(ide_dma_verbose);
 
+int ide_set_dma(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	int rc;
+
+	rc = hwif->ide_dma_check(drive);
+
+	switch(rc) {
+	case -1: /* DMA needs to be disabled */
+		return hwif->ide_dma_off_quietly(drive);
+	case  0: /* DMA needs to be enabled */
+		return hwif->ide_dma_on(drive);
+	case  1: /* DMA setting cannot be changed */
+		break;
+	default:
+		BUG();
+		break;
+	}
+
+	return rc;
+}
+
+EXPORT_SYMBOL_GPL(ide_set_dma);
+
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 int __ide_dma_lostirq (ide_drive_t *drive)
 {
Index: b/drivers/ide/ide-io.c
===================================================================
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -226,7 +226,7 @@ static ide_startstop_t ide_start_power_s
 			break;
 		if (drive->hwif->ide_dma_check == NULL)
 			break;
-		drive->hwif->ide_dma_check(drive);
+		ide_set_dma(drive);
 		break;
 	}
 	pm->pm_step = ide_pm_state_completed;
Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -857,7 +857,7 @@ static void probe_hwif(ide_hwif_t *hwif)
 #ifdef CONFIG_IDEDMA_ONLYDISK
 				if (drive->media == ide_disk)
 #endif
-					hwif->ide_dma_check(drive);
+					ide_set_dma(drive);
 			}
 		}
 	}
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1134,7 +1134,8 @@ static int set_using_dma (ide_drive_t *d
 	if (HWIF(drive)->ide_dma_check == NULL)
 		return -EPERM;
 	if (arg) {
-		if (HWIF(drive)->ide_dma_check(drive)) return -EIO;
+		if (ide_set_dma(drive))
+			return -EIO;
 		if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
 	} else {
 		if (__ide_dma_off(drive))
Index: b/drivers/ide/mips/au1xxx-ide.c
===================================================================
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -414,9 +414,9 @@ static int auide_dma_check(ide_drive_t *
 	speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);
 	
 	if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
-		return HWIF(drive)->ide_dma_on(drive);
+		return 0;
 
-	return HWIF(drive)->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static int auide_dma_test_irq(ide_drive_t *drive)
Index: b/drivers/ide/pci/aec62xx.c
===================================================================
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -209,15 +209,13 @@ static void aec62xx_tune_drive (ide_driv
 
 static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive))
 		aec62xx_tune_drive(drive, 5);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static int aec62xx_irq_timeout (ide_drive_t *drive)
Index: b/drivers/ide/pci/alim15x3.c
===================================================================
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -507,17 +507,15 @@ static int config_chipset_for_dma (ide_d
  *
  *	Configure a drive for DMA operation. If DMA is not possible we
  *	drop the drive into PIO mode instead.
- *
- *	FIXME: exactly what are we trying to return here
  */
- 
+
 static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct hd_driveid *id	= drive->id;
 
 	if ((m5229_revision<=0x20) && (drive->media!=ide_disk))
-		return hwif->ide_dma_off_quietly(drive);
+		goto no_dma_set;
 
 	drive->init_speed = 0;
 
@@ -552,9 +550,10 @@ try_dma_modes:
 ata_pio:
 		hwif->tuneproc(drive, 255);
 no_dma_set:
-		return hwif->ide_dma_off_quietly(drive);
+		return -1;
 	}
-	return hwif->ide_dma_on(drive);
+
+	return 0;
 }
 
 /**
Index: b/drivers/ide/pci/amd74xx.c
===================================================================
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -304,8 +304,9 @@ static int amd74xx_ide_dma_check(ide_dri
 	amd_set_drive(drive, speed);
 
 	if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
-		return HWIF(drive)->ide_dma_on(drive);
-	return HWIF(drive)->ide_dma_off_quietly(drive);
+		return 0;
+
+	return -1;
 }
 
 /*
Index: b/drivers/ide/pci/atiixp.c
===================================================================
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -252,21 +252,20 @@ static int atiixp_config_drive_for_dma(i
 
 static int atiixp_dma_check(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
 	u8 tspeed, speed;
 
 	drive->init_speed = 0;
 
 	if (ide_use_dma(drive) && atiixp_config_drive_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive)) {
 		tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
 		speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
-		hwif->speedproc(drive, speed);
+		atiixp_speedproc(drive, speed);
 	}
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 /**
Index: b/drivers/ide/pci/cmd64x.c
===================================================================
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -474,15 +474,13 @@ static int config_chipset_for_dma (ide_d
 
 static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive))
 		config_chipset_for_pio(drive, 1);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static int cmd64x_alt_dma_status (struct pci_dev *dev)
Index: b/drivers/ide/pci/cs5520.c
===================================================================
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -132,12 +132,11 @@ static void cs5520_tune_drive(ide_drive_
 
 static int cs5520_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = HWIF(drive);
-
 	/* Tune the drive for PIO modes up to PIO 4 */	
 	cs5520_tune_drive(drive, 4);
+
 	/* Then tell the core to use DMA operations */
-	return hwif->ide_dma_on(drive);
+	return 0;
 }
 
 /*
Index: b/drivers/ide/pci/cs5530.c
===================================================================
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -196,10 +196,7 @@ static int cs5530_config_dma (ide_drive_
 		outl(timings, basereg + 12);	/* write drive1 config register */
 	}
 
-	/*
-	 * Finally, turn DMA on in software, and exit.
-	 */
-	return hwif->ide_dma_on(drive);	/* success */
+	return 0;	/* success */
 }
 
 /**
Index: b/drivers/ide/pci/cs5535.c
===================================================================
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -195,20 +195,19 @@ static int cs5535_config_drive_for_dma(i
 
 static int cs5535_dma_check(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	u8 speed;
 
 	drive->init_speed = 0;
 
 	if (ide_use_dma(drive) && cs5535_config_drive_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive)) {
 		speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
 		cs5535_set_drive(drive, speed);
 	}
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
Index: b/drivers/ide/pci/hpt34x.c
===================================================================
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -109,21 +109,19 @@ static int config_chipset_for_dma (ide_d
 
 static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	drive->init_speed = 0;
 
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
 #ifndef CONFIG_HPT34X_AUTODMA
-		return hwif->ide_dma_off_quietly(drive);
+		return -1;
 #else
-		return hwif->ide_dma_on(drive);
+		return 0;
 #endif
 
 	if (ide_use_fast_pio(drive))
 		hpt34x_tune_drive(drive, 255);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 /*
Index: b/drivers/ide/pci/hpt366.c
===================================================================
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -736,17 +736,15 @@ static void hpt3xx_maskproc(ide_drive_t 
 
 static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	drive->init_speed = 0;
 
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive))
 		hpt3xx_tune_drive(drive, 255);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 /*
Index: b/drivers/ide/pci/it8213.c
===================================================================
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -244,17 +244,15 @@ static int config_chipset_for_dma (ide_d
 
 static int it8213_config_drive_for_dma (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
+	u8 pio;
 
-	if (ide_use_dma(drive)) {
-		if (config_chipset_for_dma(drive))
-			return hwif->ide_dma_on(drive);
-	}
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-	hwif->speedproc(drive, XFER_PIO_0
-			+ ide_get_best_pio_mode(drive, 255, 4, NULL));
+	pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
+	it8213_tune_chipset(drive, XFER_PIO_0 + pio);
 
- 	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 /**
Index: b/drivers/ide/pci/it821x.c
===================================================================
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -520,14 +520,12 @@ static int config_chipset_for_dma (ide_d
 
 static int it821x_config_drive_for_dma (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-	if (ide_use_dma(drive)) {
-		if (config_chipset_for_dma(drive))
-			return hwif->ide_dma_on(drive);
-	}
 	config_it821x_chipset_for_pio(drive, 1);
-	return hwif->ide_dma_off_quietly(drive);
+
+	return -1;
 }
 
 /**
@@ -612,7 +610,7 @@ static void __devinit it821x_fixups(ide_
 #ifdef CONFIG_IDEDMA_ONLYDISK
 			if (drive->media == ide_disk)
 #endif
-				hwif->ide_dma_check(drive);
+				ide_set_dma(drive);
 		} else {
 			/* Non RAID volume. Fixups to stop the core code
 			   doing unsupported things */
Index: b/drivers/ide/pci/jmicron.c
===================================================================
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -164,14 +164,12 @@ static int config_chipset_for_dma (ide_d
 
 static int jmicron_config_drive_for_dma (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-	if (ide_use_dma(drive)) {
-		if (config_chipset_for_dma(drive))
-			return hwif->ide_dma_on(drive);
-	}
 	config_jmicron_chipset_for_pio(drive, 1);
-	return hwif->ide_dma_off_quietly(drive);
+
+	return -1;
 }
 
 /**
Index: b/drivers/ide/pci/ns87415.c
===================================================================
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -190,7 +190,8 @@ static int ns87415_ide_dma_setup(ide_dri
 static int ns87415_ide_dma_check (ide_drive_t *drive)
 {
 	if (drive->media != ide_disk)
-		return HWIF(drive)->ide_dma_off_quietly(drive);
+		return -1;
+
 	return __ide_dma_check(drive);
 }
 
Index: b/drivers/ide/pci/pdc202xx_new.c
===================================================================
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -281,17 +281,15 @@ static int config_chipset_for_dma(ide_dr
 
 static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	drive->init_speed = 0;
 
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive))
-		hwif->tuneproc(drive, 255);
+		pdcnew_tune_drive(drive, 255);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static int pdcnew_quirkproc(ide_drive_t *drive)
Index: b/drivers/ide/pci/pdc202xx_old.c
===================================================================
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -332,17 +332,15 @@ chipset_is_set:
 
 static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	drive->init_speed = 0;
 
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive))
-		hwif->tuneproc(drive, 5);
+		config_chipset_for_pio(drive, 5);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static int pdc202xx_quirkproc (ide_drive_t *drive)
Index: b/drivers/ide/pci/piix.c
===================================================================
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -386,20 +386,18 @@ static int piix_config_drive_for_dma (id
  
 static int piix_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	drive->init_speed = 0;
 
 	if (ide_use_dma(drive) && piix_config_drive_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive)) {
 		/* Find best PIO mode. */
-		(void) hwif->speedproc(drive, XFER_PIO_0 +
-				       ide_get_best_pio_mode(drive, 255, 4, NULL));
+		u8 pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
+		(void)piix_tune_chipset(drive, XFER_PIO_0 + pio);
 	}
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 /**
Index: b/drivers/ide/pci/sc1200.c
===================================================================
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -241,10 +241,7 @@ static int sc1200_config_dma2 (ide_drive
 
 	outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2);	/* set DMA_capable bit */
 
-	/*
-	 * Finally, turn DMA on in software, and exit.
-	 */
-	return hwif->ide_dma_on(drive);	/* success */
+	return 0;	/* success */
 }
 
 /*
Index: b/drivers/ide/pci/serverworks.c
===================================================================
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -315,17 +315,15 @@ static int config_chipset_for_dma (ide_d
 
 static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	drive->init_speed = 0;
 
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive))
 		config_chipset_for_pio(drive);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const char *name)
Index: b/drivers/ide/pci/sgiioc4.c
===================================================================
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -296,9 +296,9 @@ static int sgiioc4_ide_dma_check(ide_dri
 	if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
 		printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, "
 				    "using PIO instead\n", drive->name);
-		return sgiioc4_ide_dma_off_quietly(drive);
+		return -1;
 	} else
-		return sgiioc4_ide_dma_on(drive);
+		return 0;
 }
 
 /* returns 1 if dma irq issued, 0 otherwise */
Index: b/drivers/ide/pci/siimage.c
===================================================================
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -415,15 +415,13 @@ static int config_chipset_for_dma (ide_d
  
 static int siimage_config_drive_for_dma (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive))
 		config_chipset_for_pio(drive, 1);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 /* returns 1 if dma irq issued, 0 otherwise */
Index: b/drivers/ide/pci/sis5513.c
===================================================================
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -669,19 +669,17 @@ static int config_chipset_for_dma (ide_d
 
 static int sis5513_config_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	config_art_rwp_pio(drive, 5);
 
 	drive->init_speed = 0;
 
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive))
 		sis5513_tune_drive(drive, 5);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 /* Chip detection and general config */
Index: b/drivers/ide/pci/sl82c105.c
===================================================================
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -161,14 +161,14 @@ static int sl82c105_check_drive (ide_dri
 		if (id->field_valid & 2) {
 			if ((id->dma_mword & hwif->mwdma_mask) ||
 			    (id->dma_1word & hwif->swdma_mask))
-				return hwif->ide_dma_on(drive);
+				return 0;
 		}
 
 		if (__ide_dma_good_drive(drive))
-			return hwif->ide_dma_on(drive);
+			return 0;
 	} while (0);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 /*
Index: b/drivers/ide/pci/slc90e66.c
===================================================================
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -179,19 +179,17 @@ static int slc90e66_config_drive_for_dma
 
 static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	drive->init_speed = 0;
 
 	if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive)) {
-		(void) hwif->speedproc(drive, XFER_PIO_0 +
-				       ide_get_best_pio_mode(drive, 255, 4, NULL));
+		u8 pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
+		(void)slc90e66_tune_chipset(drive, XFER_PIO_0 + pio);
 	}
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
Index: b/drivers/ide/pci/tc86c001.c
===================================================================
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -185,15 +185,13 @@ static int config_chipset_for_dma(ide_dr
 
 static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
 
 	if (ide_use_fast_pio(drive))
 		tc86c001_tune_drive(drive, 255);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
Index: b/drivers/ide/pci/triflex.c
===================================================================
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -113,13 +113,12 @@ static int triflex_config_drive_for_dma(
 
 static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	if (ide_use_dma(drive) && triflex_config_drive_for_dma(drive))
-		return hwif->ide_dma_on(drive);
+		return 0;
+
+	triflex_tune_drive(drive, 255);
 
-	hwif->tuneproc(drive, 255);
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
Index: b/drivers/ide/pci/via82cxxx.c
===================================================================
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -240,8 +240,9 @@ static int via82cxxx_ide_dma_check (ide_
 	via_set_drive(drive, speed);
 
 	if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
-		return hwif->ide_dma_on(drive);
-	return hwif->ide_dma_off_quietly(drive);
+		return 0;
+
+	return -1;
 }
 
 static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1278,6 +1278,7 @@ int __ide_dma_good_drive(ide_drive_t *);
 int ide_use_dma(ide_drive_t *);
 int __ide_dma_off(ide_drive_t *);
 void ide_dma_verbose(ide_drive_t *);
+int ide_set_dma(ide_drive_t *);
 ide_startstop_t ide_dma_intr(ide_drive_t *);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
@@ -1303,6 +1304,7 @@ extern int __ide_dma_timeout(ide_drive_t
 static inline int ide_use_dma(ide_drive_t *drive) { return 0; }
 static inline int __ide_dma_off(ide_drive_t *drive) { return 0; }
 static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
+static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
 #ifndef CONFIG_BLK_DEV_IDEDMA_PCI

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

* [PATCH 11/15] ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (9 preceding siblings ...)
  2007-01-19  0:32 ` [PATCH 10/15] ide: add ide_set_dma() helper Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:32 ` Bartlomiej Zolnierkiewicz
  2007-01-20 20:56   ` Sergei Shtylyov
  2007-01-19  0:32 ` [PATCH 12/15] ide: make ide_hwif_t.ide_dma_host_on void Bartlomiej Zolnierkiewicz
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:32 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void

* since ide_hwif_t.ide_dma_{host_off,off_quietly} always return '0'
  make these functions void and while at it drop "ide_" prefix
* fix comment for __ide_dma_off_quietly()
* make __ide_dma_{host_off,off_quietly,off}() void and drop "__" prefix

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/arm/icside.c      |   10 ++++------
 drivers/ide/cris/ide-cris.c   |   14 ++++++--------
 drivers/ide/ide-cd.c          |    6 +++---
 drivers/ide/ide-dma.c         |   39 ++++++++++++++++++---------------------
 drivers/ide/ide-floppy.c      |    8 ++++----
 drivers/ide/ide-io.c          |    2 +-
 drivers/ide/ide-iops.c        |    8 ++++----
 drivers/ide/ide-probe.c       |    2 +-
 drivers/ide/ide-tape.c        |    4 ++--
 drivers/ide/ide.c             |   10 ++++------
 drivers/ide/mips/au1xxx-ide.c |   11 ++++-------
 drivers/ide/pci/atiixp.c      |    6 +++---
 drivers/ide/pci/cs5530.c      |    2 +-
 drivers/ide/pci/it821x.c      |    2 +-
 drivers/ide/pci/sc1200.c      |    6 +++---
 drivers/ide/pci/sgiioc4.c     |   14 +++++---------
 drivers/ide/pci/sl82c105.c    |   14 ++++++--------
 drivers/ide/ppc/pmac.c        |    8 +++-----
 include/linux/ide.h           |   12 ++++++------
 19 files changed, 79 insertions(+), 99 deletions(-)

Index: b/drivers/ide/arm/icside.c
===================================================================
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -307,15 +307,13 @@ static int icside_set_speed(ide_drive_t 
 	return on;
 }
 
-static int icside_dma_host_off(ide_drive_t *drive)
+static void icside_dma_host_off(ide_drive_t *drive)
 {
-	return 0;
 }
 
-static int icside_dma_off_quietly(ide_drive_t *drive)
+static void icside_dma_off_quietly(ide_drive_t *drive)
 {
 	drive->using_dma = 0;
-	return icside_dma_host_off(drive);
 }
 
 static int icside_dma_host_on(ide_drive_t *drive)
@@ -494,8 +492,8 @@ static void icside_dma_init(ide_hwif_t *
 	hwif->autodma		= autodma;
 
 	hwif->ide_dma_check	= icside_dma_check;
-	hwif->ide_dma_host_off	= icside_dma_host_off;
-	hwif->ide_dma_off_quietly = icside_dma_off_quietly;
+	hwif->dma_host_off	= icside_dma_host_off;
+	hwif->dma_off_quietly	= icside_dma_off_quietly;
 	hwif->ide_dma_host_on	= icside_dma_host_on;
 	hwif->ide_dma_on	= icside_dma_on;
 	hwif->dma_setup		= icside_dma_setup;
Index: b/drivers/ide/cris/ide-cris.c
===================================================================
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -682,9 +682,12 @@ static void cris_ide_input_data (ide_dri
 static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int);
 static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
 static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
-static int cris_dma_off (ide_drive_t *drive);
 static int cris_dma_on (ide_drive_t *drive);
 
+static void cris_dma_off(ide_drive_t *drive)
+{
+}
+
 static void tune_cris_ide(ide_drive_t *drive, u8 pio)
 {
 	int setup, strobe, hold;
@@ -814,9 +817,9 @@ init_e100_ide (void)
 		hwif->OUTBSYNC = &cris_ide_outbsync;
 		hwif->INB = &cris_ide_inb;
 		hwif->INW = &cris_ide_inw;
-		hwif->ide_dma_host_off = &cris_dma_off;
+		hwif->dma_host_off = &cris_dma_off;
 		hwif->ide_dma_host_on = &cris_dma_on;
-		hwif->ide_dma_off_quietly = &cris_dma_off;
+		hwif->dma_off_quietly = &cris_dma_off;
 		hwif->udma_four = 0;
 		hwif->ultra_mask = cris_ultra_mask;
 		hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
@@ -838,11 +841,6 @@ init_e100_ide (void)
 	cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0);
 }
 
-static int cris_dma_off (ide_drive_t *drive)
-{
-	return 0;
-}
-
 static int cris_dma_on (ide_drive_t *drive)
 {
 	return 0;
Index: b/drivers/ide/ide-cd.c
===================================================================
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1103,7 +1103,7 @@ static ide_startstop_t cdrom_read_intr (
 	if (dma) {
 		info->dma = 0;
 		if ((dma_error = HWIF(drive)->ide_dma_end(drive)))
-			__ide_dma_off(drive);
+			ide_dma_off(drive);
 	}
 
 	if (cdrom_decode_status(drive, 0, &stat))
@@ -1699,7 +1699,7 @@ static ide_startstop_t cdrom_newpc_intr(
 	if (dma) {
 		if (dma_error) {
 			printk(KERN_ERR "ide-cd: dma error\n");
-			__ide_dma_off(drive);
+			ide_dma_off(drive);
 			return ide_error(drive, "dma error", stat);
 		}
 
@@ -1825,7 +1825,7 @@ static ide_startstop_t cdrom_write_intr(
 		info->dma = 0;
 		if ((dma_error = HWIF(drive)->ide_dma_end(drive))) {
 			printk(KERN_ERR "ide-cd: write dma error\n");
-			__ide_dma_off(drive);
+			ide_dma_off(drive);
 		}
 	}
 
Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -414,61 +414,57 @@ static int dma_timer_expiry (ide_drive_t
 }
 
 /**
- *	__ide_dma_host_off	-	Generic DMA kill
+ *	ide_dma_host_off	-	Generic DMA kill
  *	@drive: drive to control
  *
  *	Perform the generic IDE controller DMA off operation. This
  *	works for most IDE bus mastering controllers
  */
 
-int __ide_dma_host_off (ide_drive_t *drive)
+void ide_dma_host_off(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 unit			= (drive->select.b.unit & 0x01);
 	u8 dma_stat		= hwif->INB(hwif->dma_status);
 
 	hwif->OUTB((dma_stat & ~(1<<(5+unit))), hwif->dma_status);
-	return 0;
 }
 
-EXPORT_SYMBOL(__ide_dma_host_off);
+EXPORT_SYMBOL(ide_dma_host_off);
 
 /**
- *	__ide_dma_host_off_quietly	-	Generic DMA kill
+ *	ide_dma_off_quietly	-	Generic DMA kill
  *	@drive: drive to control
  *
  *	Turn off the current DMA on this IDE controller. 
  */
 
-int __ide_dma_off_quietly (ide_drive_t *drive)
+void ide_dma_off_quietly(ide_drive_t *drive)
 {
 	drive->using_dma = 0;
 	ide_toggle_bounce(drive, 0);
 
-	if (HWIF(drive)->ide_dma_host_off(drive))
-		return 1;
-
-	return 0;
+	drive->hwif->dma_host_off(drive);
 }
 
-EXPORT_SYMBOL(__ide_dma_off_quietly);
+EXPORT_SYMBOL(ide_dma_off_quietly);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 /**
- *	__ide_dma_off	-	disable DMA on a device
+ *	ide_dma_off	-	disable DMA on a device
  *	@drive: drive to disable DMA on
  *
  *	Disable IDE DMA for a device on this IDE controller.
  *	Inform the user that DMA has been disabled.
  */
 
-int __ide_dma_off (ide_drive_t *drive)
+void ide_dma_off(ide_drive_t *drive)
 {
 	printk(KERN_INFO "%s: DMA disabled\n", drive->name);
-	return HWIF(drive)->ide_dma_off_quietly(drive);
+	drive->hwif->dma_off_quietly(drive);
 }
 
-EXPORT_SYMBOL(__ide_dma_off);
+EXPORT_SYMBOL(ide_dma_off);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
@@ -758,7 +754,7 @@ void ide_dma_verbose(ide_drive_t *drive)
 	return;
 bug_dma_off:
 	printk(", BUG DMA OFF");
-	hwif->ide_dma_off_quietly(drive);
+	hwif->dma_off_quietly(drive);
 	return;
 }
 
@@ -773,7 +769,8 @@ int ide_set_dma(ide_drive_t *drive)
 
 	switch(rc) {
 	case -1: /* DMA needs to be disabled */
-		return hwif->ide_dma_off_quietly(drive);
+		hwif->dma_off_quietly(drive);
+		return 0;
 	case  0: /* DMA needs to be enabled */
 		return hwif->ide_dma_on(drive);
 	case  1: /* DMA setting cannot be changed */
@@ -937,10 +934,10 @@ void ide_setup_dma (ide_hwif_t *hwif, un
 	if (!(hwif->dma_prdtable))
 		hwif->dma_prdtable	= (hwif->dma_base + 4);
 
-	if (!hwif->ide_dma_off_quietly)
-		hwif->ide_dma_off_quietly = &__ide_dma_off_quietly;
-	if (!hwif->ide_dma_host_off)
-		hwif->ide_dma_host_off = &__ide_dma_host_off;
+	if (!hwif->dma_off_quietly)
+		hwif->dma_off_quietly = &ide_dma_off_quietly;
+	if (!hwif->dma_host_off)
+		hwif->dma_host_off = &ide_dma_host_off;
 	if (!hwif->ide_dma_on)
 		hwif->ide_dma_on = &__ide_dma_on;
 	if (!hwif->ide_dma_host_on)
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -867,7 +867,7 @@ static ide_startstop_t idefloppy_pc_intr
 	if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
 		printk(KERN_ERR "ide-floppy: The floppy wants to issue "
 			"more interrupts in DMA mode\n");
-		(void)__ide_dma_off(drive);
+		ide_dma_off(drive);
 		return ide_do_reset(drive);
 	}
 
@@ -1097,9 +1097,9 @@ static ide_startstop_t idefloppy_issue_p
 	pc->current_position = pc->buffer;
 	bcount.all = min(pc->request_transfer, 63 * 1024);
 
-	if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
-		(void)__ide_dma_off(drive);
-	}
+	if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags))
+		ide_dma_off(drive);
+
 	feature.all = 0;
 
 	if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
Index: b/drivers/ide/ide-io.c
===================================================================
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -1351,7 +1351,7 @@ static ide_startstop_t ide_dma_timeout_r
 	 */
 	drive->retry_pio++;
 	drive->state = DMA_PIO_RETRY;
-	(void) hwif->ide_dma_off_quietly(drive);
+	hwif->dma_off_quietly(drive);
 
 	/*
 	 * un-busy drive etc (hwgroup->busy is cleared on return) and
Index: b/drivers/ide/ide-iops.c
===================================================================
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -753,7 +753,7 @@ int ide_config_drive_speed (ide_drive_t 
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->ide_dma_check)	 /* check if host supports DMA */
-		hwif->ide_dma_host_off(drive);
+		hwif->dma_host_off(drive);
 #endif
 
 	/*
@@ -832,7 +832,7 @@ int ide_config_drive_speed (ide_drive_t 
 	if (speed >= XFER_SW_DMA_0)
 		hwif->ide_dma_host_on(drive);
 	else if (hwif->ide_dma_check)	/* check if host supports DMA */
-		hwif->ide_dma_off_quietly(drive);
+		hwif->dma_off_quietly(drive);
 #endif
 
 	switch(speed) {
@@ -1042,12 +1042,12 @@ static void check_dma_crc(ide_drive_t *d
 {
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (drive->crc_count) {
-		(void) HWIF(drive)->ide_dma_off_quietly(drive);
+		drive->hwif->dma_off_quietly(drive);
 		ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive));
 		if (drive->current_speed >= XFER_SW_DMA_0)
 			(void) HWIF(drive)->ide_dma_on(drive);
 	} else
-		(void)__ide_dma_off(drive);
+		ide_dma_off(drive);
 #endif
 }
 
Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -853,7 +853,7 @@ static void probe_hwif(ide_hwif_t *hwif)
 				 * things, if not checked and cleared.
 				 *   PARANOIA!!!
 				 */
-				hwif->ide_dma_off_quietly(drive);
+				hwif->dma_off_quietly(drive);
 #ifdef CONFIG_IDEDMA_ONLYDISK
 				if (drive->media == ide_disk)
 #endif
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1970,7 +1970,7 @@ static ide_startstop_t idetape_pc_intr (
 		printk(KERN_ERR "ide-tape: The tape wants to issue more "
 				"interrupts in DMA mode\n");
 		printk(KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n");
-		(void)__ide_dma_off(drive);
+		ide_dma_off(drive);
 		return ide_do_reset(drive);
 	}
 	/* Get the number of bytes to transfer on this interrupt. */
@@ -2176,7 +2176,7 @@ static ide_startstop_t idetape_issue_pac
 	if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
 		printk(KERN_WARNING "ide-tape: DMA disabled, "
 				"reverting to PIO\n");
-		(void)__ide_dma_off(drive);
+		ide_dma_off(drive);
 	}
 	if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
 		dma_ok = !hwif->dma_setup(drive);
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -506,10 +506,10 @@ static void ide_hwif_restore(ide_hwif_t 
 	hwif->ide_dma_end		= tmp_hwif->ide_dma_end;
 	hwif->ide_dma_check		= tmp_hwif->ide_dma_check;
 	hwif->ide_dma_on		= tmp_hwif->ide_dma_on;
-	hwif->ide_dma_off_quietly	= tmp_hwif->ide_dma_off_quietly;
+	hwif->dma_off_quietly		= tmp_hwif->dma_off_quietly;
 	hwif->ide_dma_test_irq		= tmp_hwif->ide_dma_test_irq;
 	hwif->ide_dma_host_on		= tmp_hwif->ide_dma_host_on;
-	hwif->ide_dma_host_off		= tmp_hwif->ide_dma_host_off;
+	hwif->dma_host_off		= tmp_hwif->dma_host_off;
 	hwif->ide_dma_lostirq		= tmp_hwif->ide_dma_lostirq;
 	hwif->ide_dma_timeout		= tmp_hwif->ide_dma_timeout;
 
@@ -1137,10 +1137,8 @@ static int set_using_dma (ide_drive_t *d
 		if (ide_set_dma(drive))
 			return -EIO;
 		if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
-	} else {
-		if (__ide_dma_off(drive))
-			return -EIO;
-	}
+	} else
+		ide_dma_off(drive);
 	return 0;
 #else
 	return -EPERM;
Index: b/drivers/ide/mips/au1xxx-ide.c
===================================================================
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -449,16 +449,13 @@ static int auide_dma_on(ide_drive_t *dri
 	return auide_dma_host_on(drive);
 }
 
-
-static int auide_dma_host_off(ide_drive_t *drive)
+static void auide_dma_host_off(ide_drive_t *drive)
 {
-	return 0;
 }
 
-static int auide_dma_off_quietly(ide_drive_t *drive)
+static void auide_dma_off_quietly(ide_drive_t *drive)
 {
 	drive->using_dma = 0;
-	return auide_dma_host_off(drive);
 }
 
 static int auide_dma_lostirq(ide_drive_t *drive)
@@ -724,7 +721,7 @@ static int au_ide_probe(struct device *d
 	hwif->speedproc                 = &auide_tune_chipset;
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-	hwif->ide_dma_off_quietly       = &auide_dma_off_quietly;
+	hwif->dma_off_quietly		= &auide_dma_off_quietly;
 	hwif->ide_dma_timeout           = &auide_dma_timeout;
 
 	hwif->ide_dma_check             = &auide_dma_check;
@@ -733,7 +730,7 @@ static int au_ide_probe(struct device *d
 	hwif->ide_dma_end               = &auide_dma_end;
 	hwif->dma_setup                 = &auide_dma_setup;
 	hwif->ide_dma_test_irq          = &auide_dma_test_irq;
-	hwif->ide_dma_host_off          = &auide_dma_host_off;
+	hwif->dma_host_off		= &auide_dma_host_off;
 	hwif->ide_dma_host_on           = &auide_dma_host_on;
 	hwif->ide_dma_lostirq           = &auide_dma_lostirq;
 	hwif->ide_dma_on                = &auide_dma_on;
Index: b/drivers/ide/pci/atiixp.c
===================================================================
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -121,7 +121,7 @@ static int atiixp_ide_dma_host_on(ide_dr
 	return __ide_dma_host_on(drive);
 }
 
-static int atiixp_ide_dma_host_off(ide_drive_t *drive)
+static void atiixp_ide_dma_host_off(ide_drive_t *drive)
 {
 	struct pci_dev *dev = drive->hwif->pci_dev;
 	unsigned long flags;
@@ -135,7 +135,7 @@ static int atiixp_ide_dma_host_off(ide_d
 
 	spin_unlock_irqrestore(&atiixp_lock, flags);
 
-	return __ide_dma_host_off(drive);
+	ide_dma_host_off(drive);
 }
 
 /**
@@ -306,7 +306,7 @@ static void __devinit init_hwif_atiixp(i
 		hwif->udma_four = 0;
 
 	hwif->ide_dma_host_on = &atiixp_ide_dma_host_on;
-	hwif->ide_dma_host_off = &atiixp_ide_dma_host_off;
+	hwif->dma_host_off = &atiixp_ide_dma_host_off;
 	hwif->ide_dma_check = &atiixp_dma_check;
 	if (!noautodma)
 		hwif->autodma = 1;
Index: b/drivers/ide/pci/cs5530.c
===================================================================
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -109,7 +109,7 @@ static int cs5530_config_dma (ide_drive_
 	/*
 	 * Default to DMA-off in case we run into trouble here.
 	 */
-	hwif->ide_dma_off_quietly(drive);
+	hwif->dma_off_quietly(drive);
 
 	/*
 	 * The CS5530 specifies that two drives sharing a cable cannot
Index: b/drivers/ide/pci/it821x.c
===================================================================
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -606,7 +606,7 @@ static void __devinit it821x_fixups(ide_
 				printk(".\n");
 			/* Now the core code will have wrongly decided no DMA
 			   so we need to fix this */
-			hwif->ide_dma_off_quietly(drive);
+			hwif->dma_off_quietly(drive);
 #ifdef CONFIG_IDEDMA_ONLYDISK
 			if (drive->media == ide_disk)
 #endif
Index: b/drivers/ide/pci/sc1200.c
===================================================================
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -161,7 +161,7 @@ static int sc1200_config_dma2 (ide_drive
 	/*
 	 * Default to DMA-off in case we run into trouble here.
 	 */
-	hwif->ide_dma_off_quietly(drive);			/* turn off DMA while we fiddle */
+	hwif->dma_off_quietly(drive);	/* turn off DMA while we fiddle */
 	outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */
 
 	/*
@@ -439,10 +439,10 @@ static int sc1200_resume (struct pci_dev
 			ide_drive_t *drive = &(hwif->drives[d]);
 			if (drive->present && !__ide_dma_bad_drive(drive)) {
 				int was_using_dma = drive->using_dma;
-				hwif->ide_dma_off_quietly(drive);
+				hwif->dma_off_quietly(drive);
 				sc1200_config_dma(drive);
 				if (!was_using_dma && drive->using_dma) {
-					hwif->ide_dma_off_quietly(drive);
+					hwif->dma_off_quietly(drive);
 				}
 			}
 		}
Index: b/drivers/ide/pci/sgiioc4.c
===================================================================
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -282,12 +282,11 @@ sgiioc4_ide_dma_on(ide_drive_t * drive)
 	return HWIF(drive)->ide_dma_host_on(drive);
 }
 
-static int
-sgiioc4_ide_dma_off_quietly(ide_drive_t * drive)
+static void sgiioc4_ide_dma_off_quietly(ide_drive_t *drive)
 {
 	drive->using_dma = 0;
 
-	return HWIF(drive)->ide_dma_host_off(drive);
+	drive->hwif->dma_host_off(drive);
 }
 
 static int sgiioc4_ide_dma_check(ide_drive_t *drive)
@@ -317,12 +316,9 @@ sgiioc4_ide_dma_host_on(ide_drive_t * dr
 	return 1;
 }
 
-static int
-sgiioc4_ide_dma_host_off(ide_drive_t * drive)
+static void sgiioc4_ide_dma_host_off(ide_drive_t * drive)
 {
 	sgiioc4_clearirq(drive);
-
-	return 0;
 }
 
 static int
@@ -612,10 +608,10 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
 	hwif->ide_dma_end = &sgiioc4_ide_dma_end;
 	hwif->ide_dma_check = &sgiioc4_ide_dma_check;
 	hwif->ide_dma_on = &sgiioc4_ide_dma_on;
-	hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
+	hwif->dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
 	hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
 	hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
-	hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
+	hwif->dma_host_off = &sgiioc4_ide_dma_host_off;
 	hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
 	hwif->ide_dma_timeout = &__ide_dma_timeout;
 
Index: b/drivers/ide/pci/sl82c105.c
===================================================================
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -261,26 +261,24 @@ static int sl82c105_ide_dma_on (ide_driv
 
 	if (config_for_dma(drive)) {
 		config_for_pio(drive, 4, 0, 0);
-		return HWIF(drive)->ide_dma_off_quietly(drive);
+		drive->hwif->dma_off_quietly(drive);
+		return 0;
 	}
 	printk(KERN_INFO "%s: DMA enabled\n", drive->name);
 	return __ide_dma_on(drive);
 }
 
-static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive)
+static void sl82c105_ide_dma_off_quietly(ide_drive_t *drive)
 {
 	u8 speed = XFER_PIO_0;
-	int rc;
-	
+
 	DBG(("sl82c105_ide_dma_off_quietly(drive:%s)\n", drive->name));
 
-	rc = __ide_dma_off_quietly(drive);
+	ide_dma_off_quietly(drive);
 	if (drive->pio_speed)
 		speed = drive->pio_speed - XFER_PIO_0;
 	config_for_pio(drive, speed, 0, 1);
 	drive->current_speed = drive->pio_speed;
-
-	return rc;
 }
 
 /*
@@ -449,7 +447,7 @@ static void __devinit init_hwif_sl82c105
 
 		hwif->ide_dma_check = &sl82c105_check_drive;
 		hwif->ide_dma_on = &sl82c105_ide_dma_on;
-		hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
+		hwif->dma_off_quietly = &sl82c105_ide_dma_off_quietly;
 		hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
 		hwif->dma_start = &sl82c105_ide_dma_start;
 		hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
Index: b/drivers/ide/ppc/pmac.c
===================================================================
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1980,10 +1980,8 @@ pmac_ide_dma_test_irq (ide_drive_t *driv
 	return 1;
 }
 
-static int
-pmac_ide_dma_host_off (ide_drive_t *drive)
+static void pmac_ide_dma_host_off(ide_drive_t *drive)
 {
-	return 0;
 }
 
 static int
@@ -2035,7 +2033,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif
 		return;
 	}
 
-	hwif->ide_dma_off_quietly = &__ide_dma_off_quietly;
+	hwif->dma_off_quietly = &ide_dma_off_quietly;
 	hwif->ide_dma_on = &__ide_dma_on;
 	hwif->ide_dma_check = &pmac_ide_dma_check;
 	hwif->dma_setup = &pmac_ide_dma_setup;
@@ -2043,7 +2041,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif
 	hwif->dma_start = &pmac_ide_dma_start;
 	hwif->ide_dma_end = &pmac_ide_dma_end;
 	hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
-	hwif->ide_dma_host_off = &pmac_ide_dma_host_off;
+	hwif->dma_host_off = &pmac_ide_dma_host_off;
 	hwif->ide_dma_host_on = &pmac_ide_dma_host_on;
 	hwif->ide_dma_timeout = &__ide_dma_timeout;
 	hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq;
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -735,10 +735,10 @@ typedef struct hwif_s {
 	int (*ide_dma_end)(ide_drive_t *drive);
 	int (*ide_dma_check)(ide_drive_t *drive);
 	int (*ide_dma_on)(ide_drive_t *drive);
-	int (*ide_dma_off_quietly)(ide_drive_t *drive);
+	void (*dma_off_quietly)(ide_drive_t *);
 	int (*ide_dma_test_irq)(ide_drive_t *drive);
 	int (*ide_dma_host_on)(ide_drive_t *drive);
-	int (*ide_dma_host_off)(ide_drive_t *drive);
+	void (*dma_host_off)(ide_drive_t *);
 	int (*ide_dma_lostirq)(ide_drive_t *drive);
 	int (*ide_dma_timeout)(ide_drive_t *drive);
 
@@ -1276,7 +1276,7 @@ int ide_in_drive_list(struct hd_driveid 
 int __ide_dma_bad_drive(ide_drive_t *);
 int __ide_dma_good_drive(ide_drive_t *);
 int ide_use_dma(ide_drive_t *);
-int __ide_dma_off(ide_drive_t *);
+void ide_dma_off(ide_drive_t *);
 void ide_dma_verbose(ide_drive_t *);
 int ide_set_dma(ide_drive_t *);
 ide_startstop_t ide_dma_intr(ide_drive_t *);
@@ -1288,8 +1288,8 @@ extern void ide_destroy_dmatable(ide_dri
 extern int ide_release_dma(ide_hwif_t *);
 extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int);
 
-extern int __ide_dma_host_off(ide_drive_t *);
-extern int __ide_dma_off_quietly(ide_drive_t *);
+void ide_dma_host_off(ide_drive_t *);
+void ide_dma_off_quietly(ide_drive_t *);
 extern int __ide_dma_host_on(ide_drive_t *);
 extern int __ide_dma_on(ide_drive_t *);
 extern int __ide_dma_check(ide_drive_t *);
@@ -1302,7 +1302,7 @@ extern int __ide_dma_timeout(ide_drive_t
 
 #else
 static inline int ide_use_dma(ide_drive_t *drive) { return 0; }
-static inline int __ide_dma_off(ide_drive_t *drive) { return 0; }
+static inline void ide_dma_off(ide_drive_t *drive) { ; }
 static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
 static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
 #endif /* CONFIG_BLK_DEV_IDEDMA */

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

* [PATCH 12/15] ide: make ide_hwif_t.ide_dma_host_on void
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (10 preceding siblings ...)
  2007-01-19  0:32 ` [PATCH 11/15] ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:32 ` Bartlomiej Zolnierkiewicz
  2007-01-20 20:46   ` Sergei Shtylyov
  2007-03-26 17:19   ` Sergei Shtylyov
  2007-01-19  0:32 ` [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks Bartlomiej Zolnierkiewicz
                   ` (2 subsequent siblings)
  14 siblings, 2 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:32 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] ide: make ide_hwif_t.ide_dma_host_on void

* since ide_hwif_t.ide_dma_host_on is called either when drive->using_dma == 1
  or when return value is discarded make it void, also drop "ide_" prefix
* make __ide_dma_host_on() void and drop "__" prefix

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/arm/icside.c      |    8 ++++----
 drivers/ide/cris/ide-cris.c   |    2 +-
 drivers/ide/ide-dma.c         |   17 +++++++----------
 drivers/ide/ide-iops.c        |    2 +-
 drivers/ide/ide.c             |    2 +-
 drivers/ide/mips/au1xxx-ide.c |    8 ++++----
 drivers/ide/pci/atiixp.c      |    6 +++---
 drivers/ide/pci/sgiioc4.c     |   11 +++--------
 drivers/ide/ppc/pmac.c        |    6 ++----
 include/linux/ide.h           |    4 ++--
 10 files changed, 28 insertions(+), 38 deletions(-)

Index: b/drivers/ide/arm/icside.c
===================================================================
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -316,15 +316,15 @@ static void icside_dma_off_quietly(ide_d
 	drive->using_dma = 0;
 }
 
-static int icside_dma_host_on(ide_drive_t *drive)
+static void icside_dma_host_on(ide_drive_t *drive)
 {
-	return 0;
 }
 
 static int icside_dma_on(ide_drive_t *drive)
 {
 	drive->using_dma = 1;
-	return icside_dma_host_on(drive);
+
+	return 0;
 }
 
 static int icside_dma_check(ide_drive_t *drive)
@@ -494,7 +494,7 @@ static void icside_dma_init(ide_hwif_t *
 	hwif->ide_dma_check	= icside_dma_check;
 	hwif->dma_host_off	= icside_dma_host_off;
 	hwif->dma_off_quietly	= icside_dma_off_quietly;
-	hwif->ide_dma_host_on	= icside_dma_host_on;
+	hwif->dma_host_on	= icside_dma_host_on;
 	hwif->ide_dma_on	= icside_dma_on;
 	hwif->dma_setup		= icside_dma_setup;
 	hwif->dma_exec_cmd	= icside_dma_exec_cmd;
Index: b/drivers/ide/cris/ide-cris.c
===================================================================
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -818,7 +818,7 @@ init_e100_ide (void)
 		hwif->INB = &cris_ide_inb;
 		hwif->INW = &cris_ide_inw;
 		hwif->dma_host_off = &cris_dma_off;
-		hwif->ide_dma_host_on = &cris_dma_on;
+		hwif->dma_host_on = &cris_dma_on;
 		hwif->dma_off_quietly = &cris_dma_off;
 		hwif->udma_four = 0;
 		hwif->ultra_mask = cris_ultra_mask;
Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -468,14 +468,14 @@ EXPORT_SYMBOL(ide_dma_off);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
- *	__ide_dma_host_on	-	Enable DMA on a host
+ *	ide_dma_host_on	-	Enable DMA on a host
  *	@drive: drive to enable for DMA
  *
  *	Enable DMA on an IDE controller following generic bus mastering
  *	IDE controller behaviour
  */
- 
-int __ide_dma_host_on (ide_drive_t *drive)
+
+void ide_dma_host_on(ide_drive_t *drive)
 {
 	if (drive->using_dma) {
 		ide_hwif_t *hwif	= HWIF(drive);
@@ -483,12 +483,10 @@ int __ide_dma_host_on (ide_drive_t *driv
 		u8 dma_stat		= hwif->INB(hwif->dma_status);
 
 		hwif->OUTB((dma_stat|(1<<(5+unit))), hwif->dma_status);
-		return 0;
 	}
-	return 1;
 }
 
-EXPORT_SYMBOL(__ide_dma_host_on);
+EXPORT_SYMBOL(ide_dma_host_on);
 
 /**
  *	__ide_dma_on		-	Enable DMA on a device
@@ -506,8 +504,7 @@ int __ide_dma_on (ide_drive_t *drive)
 	drive->using_dma = 1;
 	ide_toggle_bounce(drive, 1);
 
-	if (HWIF(drive)->ide_dma_host_on(drive))
-		return 1;
+	drive->hwif->dma_host_on(drive);
 
 	return 0;
 }
@@ -940,8 +937,8 @@ void ide_setup_dma (ide_hwif_t *hwif, un
 		hwif->dma_host_off = &ide_dma_host_off;
 	if (!hwif->ide_dma_on)
 		hwif->ide_dma_on = &__ide_dma_on;
-	if (!hwif->ide_dma_host_on)
-		hwif->ide_dma_host_on = &__ide_dma_host_on;
+	if (!hwif->dma_host_on)
+		hwif->dma_host_on = &ide_dma_host_on;
 	if (!hwif->ide_dma_check)
 		hwif->ide_dma_check = &__ide_dma_check;
 	if (!hwif->dma_setup)
Index: b/drivers/ide/ide-iops.c
===================================================================
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -830,7 +830,7 @@ int ide_config_drive_speed (ide_drive_t 
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (speed >= XFER_SW_DMA_0)
-		hwif->ide_dma_host_on(drive);
+		hwif->dma_host_on(drive);
 	else if (hwif->ide_dma_check)	/* check if host supports DMA */
 		hwif->dma_off_quietly(drive);
 #endif
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -508,7 +508,7 @@ static void ide_hwif_restore(ide_hwif_t 
 	hwif->ide_dma_on		= tmp_hwif->ide_dma_on;
 	hwif->dma_off_quietly		= tmp_hwif->dma_off_quietly;
 	hwif->ide_dma_test_irq		= tmp_hwif->ide_dma_test_irq;
-	hwif->ide_dma_host_on		= tmp_hwif->ide_dma_host_on;
+	hwif->dma_host_on		= tmp_hwif->dma_host_on;
 	hwif->dma_host_off		= tmp_hwif->dma_host_off;
 	hwif->ide_dma_lostirq		= tmp_hwif->ide_dma_lostirq;
 	hwif->ide_dma_timeout		= tmp_hwif->ide_dma_timeout;
Index: b/drivers/ide/mips/au1xxx-ide.c
===================================================================
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -438,15 +438,15 @@ static int auide_dma_test_irq(ide_drive_
 	return 0;
 }
 
-static int auide_dma_host_on(ide_drive_t *drive)
+static void auide_dma_host_on(ide_drive_t *drive)
 {
-	return 0;
 }
 
 static int auide_dma_on(ide_drive_t *drive)
 {
 	drive->using_dma = 1;
-	return auide_dma_host_on(drive);
+
+	return 0;
 }
 
 static void auide_dma_host_off(ide_drive_t *drive)
@@ -731,7 +731,7 @@ static int au_ide_probe(struct device *d
 	hwif->dma_setup                 = &auide_dma_setup;
 	hwif->ide_dma_test_irq          = &auide_dma_test_irq;
 	hwif->dma_host_off		= &auide_dma_host_off;
-	hwif->ide_dma_host_on           = &auide_dma_host_on;
+	hwif->dma_host_on		= &auide_dma_host_on;
 	hwif->ide_dma_lostirq           = &auide_dma_lostirq;
 	hwif->ide_dma_on                = &auide_dma_on;
 
Index: b/drivers/ide/pci/atiixp.c
===================================================================
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -101,7 +101,7 @@ static u8 atiixp_dma_2_pio(u8 xfer_rate)
 	}
 }
 
-static int atiixp_ide_dma_host_on(ide_drive_t *drive)
+static void atiixp_ide_dma_host_on(ide_drive_t *drive)
 {
 	struct pci_dev *dev = drive->hwif->pci_dev;
 	unsigned long flags;
@@ -118,7 +118,7 @@ static int atiixp_ide_dma_host_on(ide_dr
 
 	spin_unlock_irqrestore(&atiixp_lock, flags);
 
-	return __ide_dma_host_on(drive);
+	ide_dma_host_on(drive);
 }
 
 static void atiixp_ide_dma_host_off(ide_drive_t *drive)
@@ -305,7 +305,7 @@ static void __devinit init_hwif_atiixp(i
 	else
 		hwif->udma_four = 0;
 
-	hwif->ide_dma_host_on = &atiixp_ide_dma_host_on;
+	hwif->dma_host_on = &atiixp_ide_dma_host_on;
 	hwif->dma_host_off = &atiixp_ide_dma_host_off;
 	hwif->ide_dma_check = &atiixp_dma_check;
 	if (!noautodma)
Index: b/drivers/ide/pci/sgiioc4.c
===================================================================
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -279,7 +279,7 @@ sgiioc4_ide_dma_on(ide_drive_t * drive)
 {
 	drive->using_dma = 1;
 
-	return HWIF(drive)->ide_dma_host_on(drive);
+	return 0;
 }
 
 static void sgiioc4_ide_dma_off_quietly(ide_drive_t *drive)
@@ -307,13 +307,8 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * d
 	return sgiioc4_checkirq(HWIF(drive));
 }
 
-static int
-sgiioc4_ide_dma_host_on(ide_drive_t * drive)
+static void sgiioc4_ide_dma_host_on(ide_drive_t * drive)
 {
-	if (drive->using_dma)
-		return 0;
-
-	return 1;
 }
 
 static void sgiioc4_ide_dma_host_off(ide_drive_t * drive)
@@ -610,7 +605,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
 	hwif->ide_dma_on = &sgiioc4_ide_dma_on;
 	hwif->dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
 	hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
-	hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
+	hwif->dma_host_on = &sgiioc4_ide_dma_host_on;
 	hwif->dma_host_off = &sgiioc4_ide_dma_host_off;
 	hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
 	hwif->ide_dma_timeout = &__ide_dma_timeout;
Index: b/drivers/ide/ppc/pmac.c
===================================================================
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1984,10 +1984,8 @@ static void pmac_ide_dma_host_off(ide_dr
 {
 }
 
-static int
-pmac_ide_dma_host_on (ide_drive_t *drive)
+static int pmac_ide_dma_host_on(ide_drive_t *drive)
 {
-	return 0;
 }
 
 static int
@@ -2042,7 +2040,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif
 	hwif->ide_dma_end = &pmac_ide_dma_end;
 	hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
 	hwif->dma_host_off = &pmac_ide_dma_host_off;
-	hwif->ide_dma_host_on = &pmac_ide_dma_host_on;
+	hwif->dma_host_on = &pmac_ide_dma_host_on;
 	hwif->ide_dma_timeout = &__ide_dma_timeout;
 	hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq;
 
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -737,7 +737,7 @@ typedef struct hwif_s {
 	int (*ide_dma_on)(ide_drive_t *drive);
 	void (*dma_off_quietly)(ide_drive_t *);
 	int (*ide_dma_test_irq)(ide_drive_t *drive);
-	int (*ide_dma_host_on)(ide_drive_t *drive);
+	void (*dma_host_on)(ide_drive_t *);
 	void (*dma_host_off)(ide_drive_t *);
 	int (*ide_dma_lostirq)(ide_drive_t *drive);
 	int (*ide_dma_timeout)(ide_drive_t *drive);
@@ -1290,7 +1290,7 @@ extern void ide_setup_dma(ide_hwif_t *, 
 
 void ide_dma_host_off(ide_drive_t *);
 void ide_dma_off_quietly(ide_drive_t *);
-extern int __ide_dma_host_on(ide_drive_t *);
+void ide_dma_host_on(ide_drive_t *);
 extern int __ide_dma_on(ide_drive_t *);
 extern int __ide_dma_check(ide_drive_t *);
 extern int ide_dma_setup(ide_drive_t *);

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

* [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (11 preceding siblings ...)
  2007-01-19  0:32 ` [PATCH 12/15] ide: make ide_hwif_t.ide_dma_host_on void Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:32 ` Bartlomiej Zolnierkiewicz
  2007-01-22 16:19   ` Sergei Shtylyov
  2007-01-22 18:17   ` Sergei Shtylyov
  2007-01-19  0:32 ` [PATCH 14/15] ide: rework the code for selecting the best DMA transfer mode Bartlomiej Zolnierkiewicz
  2007-01-19  0:32 ` [PATCH 15/15] ide: add ide_tune_dma() helper Bartlomiej Zolnierkiewicz
  14 siblings, 2 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:32 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] ide: fix UDMA/MWDMA/SWDMA masks

* use 0x00 instead of 0x80 to disable ->{ultra,mwdma,swdma}_mask
* add udma_mask field to ide_pci_device_t and use it to initialize
  ->ultra_mask in aec62xx, pdc202xx_new and pdc202xx_old drivers
* fix UDMA masks to match with chipset specific *_ratemask()
  (alim15x3, hpt366, serverworks and siimage drivers need UDMA mask
   filtering method - done in the next patch)

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/ide.c              |    3 ---
 drivers/ide/pci/aec62xx.c      |   20 ++++++++++++++++++--
 drivers/ide/pci/alim15x3.c     |   13 +++++++++++--
 drivers/ide/pci/cmd64x.c       |    5 +++--
 drivers/ide/pci/pdc202xx_new.c |    9 ++++++++-
 drivers/ide/pci/pdc202xx_old.c |    7 ++++++-
 drivers/ide/pci/piix.c         |    6 +++++-
 drivers/ide/pci/sis5513.c      |    5 ++++-
 include/linux/ide.h            |    1 +
 9 files changed, 56 insertions(+), 13 deletions(-)

Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -222,9 +222,6 @@ static void init_hwif_data(ide_hwif_t *h
 	hwif->bus_state	= BUSSTATE_ON;
 
 	hwif->atapi_dma = 0;		/* disable all atapi dma */ 
-	hwif->ultra_mask = 0x80;	/* disable all ultra */
-	hwif->mwdma_mask = 0x80;	/* disable all mwdma */
-	hwif->swdma_mask = 0x80;	/* disable all swdma */
 
 	init_completion(&hwif->gendev_rel_comp);
 
Index: b/drivers/ide/pci/aec62xx.c
===================================================================
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -270,11 +270,13 @@ static unsigned int __devinit init_chips
 
 static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
 {
+	struct pci_dev *dev = hwif->pci_dev;
+
 	hwif->autodma = 0;
 	hwif->tuneproc = &aec62xx_tune_drive;
 	hwif->speedproc = &aec62xx_tune_chipset;
 
-	if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
+	if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
 		hwif->serialized = hwif->channel;
 
 	if (hwif->mate)
@@ -286,7 +288,16 @@ static void __devinit init_hwif_aec62xx(
 		return;
 	}
 
-	hwif->ultra_mask = 0x7f;
+	hwif->ultra_mask = hwif->cds->udma_mask;
+
+	/* atp865 and atp865r */
+	if (hwif->ultra_mask == 0x3f) {
+		unsigned long io = pci_resource_start(dev, 4);
+
+		if (inb(io) & 0x10)
+ 			hwif->ultra_mask = 0x7f; /* udma0-6 */
+	}
+
 	hwif->mwdma_mask = 0x07;
 	hwif->swdma_mask = 0x07;
 
@@ -354,6 +365,7 @@ static ide_pci_device_t aec62xx_chipsets
 		.autodma	= AUTODMA,
 		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
 		.bootable	= OFF_BOARD,
+		.udma_mask	= 0x07, /* udma0-2 */
 	},{	/* 1 */
 		.name		= "AEC6260",
 		.init_setup	= init_setup_aec62xx,
@@ -363,6 +375,7 @@ static ide_pci_device_t aec62xx_chipsets
 		.channels	= 2,
 		.autodma	= NOAUTODMA,
 		.bootable	= OFF_BOARD,
+		.udma_mask	= 0x1f, /* udma0-4 */
 	},{	/* 2 */
 		.name		= "AEC6260R",
 		.init_setup	= init_setup_aec62xx,
@@ -373,6 +386,7 @@ static ide_pci_device_t aec62xx_chipsets
 		.autodma	= AUTODMA,
 		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
 		.bootable	= NEVER_BOARD,
+		.udma_mask	= 0x1f, /* udma0-4 */
 	},{	/* 3 */
 		.name		= "AEC6X80",
 		.init_setup	= init_setup_aec6x80,
@@ -382,6 +396,7 @@ static ide_pci_device_t aec62xx_chipsets
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
+		.udma_mask	= 0x3f, /* udma0-5 */
 	},{	/* 4 */
 		.name		= "AEC6X80R",
 		.init_setup	= init_setup_aec6x80,
@@ -392,6 +407,7 @@ static ide_pci_device_t aec62xx_chipsets
 		.autodma	= AUTODMA,
 		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
 		.bootable	= OFF_BOARD,
+		.udma_mask	= 0x3f, /* udma0-5 */
 	}
 };
 
Index: b/drivers/ide/pci/alim15x3.c
===================================================================
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -765,8 +765,17 @@ static void __devinit init_hwif_common_a
 
 	hwif->atapi_dma = 1;
 
-	if (m5229_revision > 0x20)
-		hwif->ultra_mask = 0x7f;
+	if (m5229_revision <= 0x20)
+		hwif->ultra_mask = 0x00; /* no udma */
+	else if (m5229_revision < 0xC2)
+		hwif->ultra_mask = 0x07; /* udma0-2 */
+	else if (m5229_revision == 0xC2 || m5229_revision == 0xC3)
+		hwif->ultra_mask = 0x1f; /* udma0-4 */
+	else if (m5229_revision == 0xC4)
+		hwif->ultra_mask = 0x3f; /* udma0-5 */
+	else
+		hwif->ultra_mask = 0x7f; /* udma0-6 */
+
 	hwif->mwdma_mask = 0x07;
 	hwif->swdma_mask = 0x07;
 
Index: b/drivers/ide/pci/cmd64x.c
===================================================================
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -695,9 +695,10 @@ static void __devinit init_hwif_cmd64x(i
 	hwif->swdma_mask = 0x07;
 
 	if (dev->device == PCI_DEVICE_ID_CMD_643)
-		hwif->ultra_mask = 0x80;
+		hwif->ultra_mask = 0x00;
 	if (dev->device == PCI_DEVICE_ID_CMD_646)
-		hwif->ultra_mask = (class_rev > 0x04) ? 0x07 : 0x80;
+		hwif->ultra_mask =
+			(class_rev == 0x05 || class_rev == 0x07) ? 0x07 : 0x00;
 	if (dev->device == PCI_DEVICE_ID_CMD_648)
 		hwif->ultra_mask = 0x1f;
 
Index: b/drivers/ide/pci/pdc202xx_new.c
===================================================================
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -545,7 +545,7 @@ static void __devinit init_hwif_pdc202ne
 
 	hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
 
-	hwif->ultra_mask = 0x7f;
+	hwif->ultra_mask = hwif->cds->udma_mask;
 	hwif->mwdma_mask = 0x07;
 
 	hwif->err_stops_fifo = 1;
@@ -621,6 +621,7 @@ static ide_pci_device_t pdcnew_chipsets[
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
+		.udma_mask	= 0x3f, /* udma0-5 */
 	},{	/* 1 */
 		.name		= "PDC20269",
 		.init_setup	= init_setup_pdcnew,
@@ -629,6 +630,7 @@ static ide_pci_device_t pdcnew_chipsets[
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
+		.udma_mask	= 0x7f, /* udma0-6*/
 	},{	/* 2 */
 		.name		= "PDC20270",
 		.init_setup	= init_setup_pdc20270,
@@ -637,6 +639,7 @@ static ide_pci_device_t pdcnew_chipsets[
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
+		.udma_mask	= 0x3f, /* udma0-5 */
 	},{	/* 3 */
 		.name		= "PDC20271",
 		.init_setup	= init_setup_pdcnew,
@@ -645,6 +648,7 @@ static ide_pci_device_t pdcnew_chipsets[
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
+		.udma_mask	= 0x7f, /* udma0-6*/
 	},{	/* 4 */
 		.name		= "PDC20275",
 		.init_setup	= init_setup_pdcnew,
@@ -653,6 +657,7 @@ static ide_pci_device_t pdcnew_chipsets[
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
+		.udma_mask	= 0x7f, /* udma0-6*/
 	},{	/* 5 */
 		.name		= "PDC20276",
 		.init_setup	= init_setup_pdc20276,
@@ -661,6 +666,7 @@ static ide_pci_device_t pdcnew_chipsets[
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
+		.udma_mask	= 0x7f, /* udma0-6*/
 	},{	/* 6 */
 		.name		= "PDC20277",
 		.init_setup	= init_setup_pdcnew,
@@ -669,6 +675,7 @@ static ide_pci_device_t pdcnew_chipsets[
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
+		.udma_mask	= 0x7f, /* udma0-6*/
 	}
 };
 
Index: b/drivers/ide/pci/pdc202xx_old.c
===================================================================
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -488,7 +488,7 @@ static void __devinit init_hwif_pdc202xx
 
 	hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
 
-	hwif->ultra_mask = 0x3f;
+	hwif->ultra_mask = hwif->cds->udma_mask;
 	hwif->mwdma_mask = 0x07;
 	hwif->swdma_mask = 0x07;
 	hwif->atapi_dma = 1;
@@ -597,6 +597,7 @@ static ide_pci_device_t pdc202xx_chipset
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
 		.extra		= 16,
+		.udma_mask	= 0x07, /* udma0-2 */
 	},{	/* 1 */
 		.name		= "PDC20262",
 		.init_setup	= init_setup_pdc202ata4,
@@ -607,6 +608,7 @@ static ide_pci_device_t pdc202xx_chipset
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
 		.extra		= 48,
+		.udma_mask	= 0x1f, /* udma0-4 */
 	},{	/* 2 */
 		.name		= "PDC20263",
 		.init_setup	= init_setup_pdc202ata4,
@@ -617,6 +619,7 @@ static ide_pci_device_t pdc202xx_chipset
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
 		.extra		= 48,
+		.udma_mask	= 0x1f, /* udma0-4 */
 	},{	/* 3 */
 		.name		= "PDC20265",
 		.init_setup	= init_setup_pdc20265,
@@ -627,6 +630,7 @@ static ide_pci_device_t pdc202xx_chipset
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
 		.extra		= 48,
+		.udma_mask	= 0x3f, /* udma0-5 */
 	},{	/* 4 */
 		.name		= "PDC20267",
 		.init_setup	= init_setup_pdc202xx,
@@ -637,6 +641,7 @@ static ide_pci_device_t pdc202xx_chipset
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
 		.extra		= 48,
+		.udma_mask	= 0x3f, /* udma0-5 */
 	}
 };
 
Index: b/drivers/ide/pci/piix.c
===================================================================
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -493,7 +493,7 @@ static void __devinit init_hwif_piix(ide
 		case PCI_DEVICE_ID_INTEL_82371FB_0:
 		case PCI_DEVICE_ID_INTEL_82371FB_1:
 		case PCI_DEVICE_ID_INTEL_82371SB_1:
-			hwif->ultra_mask = 0x80;
+			hwif->ultra_mask = 0x00;
 			break;
 		case PCI_DEVICE_ID_INTEL_82371AB:
 		case PCI_DEVICE_ID_INTEL_82443MX_1:
@@ -501,6 +501,10 @@ static void __devinit init_hwif_piix(ide
 		case PCI_DEVICE_ID_INTEL_82801AB_1:
 			hwif->ultra_mask = 0x07;
 			break;
+		case PCI_DEVICE_ID_INTEL_82801AA_1:
+		case PCI_DEVICE_ID_INTEL_82372FB_1:
+			hwif->ultra_mask = 0x1f;
+			break;
 		default:
 			if (!hwif->udma_four)
 				hwif->udma_four = piix_cable_detect(hwif);
Index: b/drivers/ide/pci/sis5513.c
===================================================================
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -858,6 +858,8 @@ static unsigned int __devinit ata66_sis5
 
 static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
 {
+	u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f };
+
 	hwif->autodma = 0;
 
 	if (!hwif->irq)
@@ -873,7 +875,8 @@ static void __devinit init_hwif_sis5513 
 	}
 
 	hwif->atapi_dma = 1;
-	hwif->ultra_mask = 0x7f;
+
+	hwif->ultra_mask = udma_rates[chipset_family];
 	hwif->mwdma_mask = 0x07;
 	hwif->swdma_mask = 0x07;
 
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1255,6 +1255,7 @@ typedef struct ide_pci_device_s {
 	unsigned int		extra;
 	struct ide_pci_device_s	*next;
 	u8			flags;
+	u8			udma_mask;
 } ide_pci_device_t;
 
 extern int ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);

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

* [PATCH 14/15] ide: rework the code for selecting the best DMA transfer mode
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (12 preceding siblings ...)
  2007-01-19  0:32 ` [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:32 ` Bartlomiej Zolnierkiewicz
  2007-01-22 19:48   ` Sergei Shtylyov
  2007-01-19  0:32 ` [PATCH 15/15] ide: add ide_tune_dma() helper Bartlomiej Zolnierkiewicz
  14 siblings, 1 reply; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:32 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] ide: rework the code for selecting the best DMA transfer mode 

Depends on the "ide: fix UDMA/MWDMA/SWDMA masks" patch.

* add ide_hwif_t.filter_udma_mask hook for filtering UDMA mask
  (use it in alim15x3, hpt366, siimage and serverworks drivers)
* add ide_max_dma_mode() for finding best DMA mode for the device
  (loosely based on some older libata-core.c code)
* convert ide_dma_speed() users to use ide_max_dma_mode()
* make ide_rate_filter() take "ide_drive_t *drive" as an argument instead
  of "u8 mode" and teach it to how to use UDMA mask to do filtering
* use ide_rate_filter() in hpt366 driver
* remove no longer needed ide_dma_speed() and *_ratemask()
* unexport eighty_ninty_three()

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/arm/icside.c       |    2 
 drivers/ide/cris/ide-cris.c    |    2 
 drivers/ide/ide-dma.c          |   74 ++++++++++++++++++++++++
 drivers/ide/ide-iops.c         |    2 
 drivers/ide/ide-lib.c          |  125 +++++------------------------------------
 drivers/ide/ide.c              |    1 
 drivers/ide/pci/aec62xx.c      |   32 ----------
 drivers/ide/pci/alim15x3.c     |   76 +++++-------------------
 drivers/ide/pci/atiixp.c       |   20 ------
 drivers/ide/pci/cmd64x.c       |   66 ++++-----------------
 drivers/ide/pci/cs5535.c       |   20 ------
 drivers/ide/pci/hpt34x.c       |    9 --
 drivers/ide/pci/hpt366.c       |   67 +++++++++++----------
 drivers/ide/pci/it8213.c       |   20 ------
 drivers/ide/pci/it821x.c       |   20 ------
 drivers/ide/pci/jmicron.c      |   21 ------
 drivers/ide/pci/pdc202xx_new.c |   14 ----
 drivers/ide/pci/pdc202xx_old.c |   27 --------
 drivers/ide/pci/piix.c         |   66 ---------------------
 drivers/ide/pci/serverworks.c  |   31 ++++++----
 drivers/ide/pci/siimage.c      |   45 ++++++--------
 drivers/ide/pci/sis5513.c      |   14 ----
 drivers/ide/pci/slc90e66.c     |   13 ----
 drivers/ide/pci/tc86c001.c     |    9 --
 drivers/ide/pci/triflex.c      |    4 -
 include/linux/ide.h            |   10 +--
 26 files changed, 235 insertions(+), 555 deletions(-)

Index: b/drivers/ide/arm/icside.c
===================================================================
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -347,7 +347,7 @@ static int icside_dma_check(ide_drive_t 
 	 * Enable DMA on any drive that has multiword DMA
 	 */
 	if (id->field_valid & 2) {
-		xfer_mode = ide_dma_speed(drive, 0);
+		xfer_mode = ide_max_dma_mode(drive);
 		goto out;
 	}
 
Index: b/drivers/ide/cris/ide-cris.c
===================================================================
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -1006,7 +1006,7 @@ static int cris_ide_build_dmatable (ide_
 
 static int cris_config_drive_for_dma (ide_drive_t *drive)
 {
-	u8 speed = ide_dma_speed(drive, 1);
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!speed)
 		return 0;
Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -705,6 +705,80 @@ int ide_use_dma(ide_drive_t *drive)
 
 EXPORT_SYMBOL_GPL(ide_use_dma);
 
+static const u8 xfer_mode_bases[] = {
+	XFER_UDMA_0,
+	XFER_MW_DMA_0,
+	XFER_SW_DMA_0,
+};
+
+static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base)
+{
+	struct hd_driveid *id = drive->id;
+	ide_hwif_t *hwif = drive->hwif;
+	unsigned int mask = 0;
+
+	switch(base) {
+	case XFER_UDMA_0:
+		if ((id->field_valid & 4) == 0)
+			break;
+
+		mask = id->dma_ultra & hwif->ultra_mask;
+
+		if (hwif->filter_udma_mask)
+			mask &= hwif->filter_udma_mask(drive);
+
+		if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
+			mask &= 0x07;
+		break;
+	case XFER_MW_DMA_0:
+		mask = id->dma_mword & hwif->mwdma_mask;
+		break;
+	case XFER_SW_DMA_0:
+		mask = id->dma_1word & hwif->swdma_mask;
+		break;
+	default:
+		BUG();
+		break;
+	}
+
+	return mask;
+}
+
+/**
+ *	ide_max_dma_mode	-	compute DMA speed
+ *	@drive: IDE device
+ *
+ *	Checks the drive capabilities and returns the speed to use
+ *	for the DMA transfer.  Returns 0 if the drive is incapable
+ *	of DMA transfers.
+ */
+
+u8 ide_max_dma_mode(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	unsigned int mask;
+	int x, i;
+	u8 mode = 0;
+
+	if (drive->media != ide_disk && hwif->atapi_dma == 0)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) {
+		mask = ide_get_mode_mask(drive, xfer_mode_bases[i]);
+		x = fls(mask) - 1;
+		if (x >= 0) {
+			mode = xfer_mode_bases[i] + x;
+			break;
+		}
+	}
+
+	printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode);
+
+	return mode;
+}
+
+EXPORT_SYMBOL_GPL(ide_max_dma_mode);
+
 void ide_dma_verbose(ide_drive_t *drive)
 {
 	struct hd_driveid *id	= drive->id;
Index: b/drivers/ide/ide-iops.c
===================================================================
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -586,8 +586,6 @@ u8 eighty_ninty_three (ide_drive_t *driv
 	return 1;
 }
 
-EXPORT_SYMBOL(eighty_ninty_three);
-
 int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
 {
 	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
Index: b/drivers/ide/ide-lib.c
===================================================================
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -69,123 +69,34 @@ char *ide_xfer_verbose (u8 xfer_rate)
 EXPORT_SYMBOL(ide_xfer_verbose);
 
 /**
- *	ide_dma_speed	-	compute DMA speed
- *	@drive: drive
- *	@mode:	modes available
- *
- *	Checks the drive capabilities and returns the speed to use
- *	for the DMA transfer.  Returns 0 if the drive is incapable
- *	of DMA transfers.
- */
- 
-u8 ide_dma_speed(ide_drive_t *drive, u8 mode)
-{
-	struct hd_driveid *id   = drive->id;
-	ide_hwif_t *hwif	= HWIF(drive);
-	u8 ultra_mask, mwdma_mask, swdma_mask;
-	u8 speed = 0;
-
-	if (drive->media != ide_disk && hwif->atapi_dma == 0)
-		return 0;
-
-	/* Capable of UltraDMA modes? */
-	ultra_mask = id->dma_ultra & hwif->ultra_mask;
-
-	if (!(id->field_valid & 4))
-		mode = 0;	/* fallback to MW/SW DMA if no UltraDMA */
-
-	switch (mode) {
-	case 4:
-		if (ultra_mask & 0x40) {
-			speed = XFER_UDMA_6;
-			break;
-		}
-	case 3:
-		if (ultra_mask & 0x20) {
-			speed = XFER_UDMA_5;
-			break;
-		}
-	case 2:
-		if (ultra_mask & 0x10) {
-			speed = XFER_UDMA_4;
-			break;
-		}
-		if (ultra_mask & 0x08) {
-			speed = XFER_UDMA_3;
-			break;
-		}
-	case 1:
-		if (ultra_mask & 0x04) {
-			speed = XFER_UDMA_2;
-			break;
-		}
-		if (ultra_mask & 0x02) {
-			speed = XFER_UDMA_1;
-			break;
-		}
-		if (ultra_mask & 0x01) {
-			speed = XFER_UDMA_0;
-			break;
-		}
-	case 0:
-		mwdma_mask = id->dma_mword & hwif->mwdma_mask;
-
-		if (mwdma_mask & 0x04) {
-			speed = XFER_MW_DMA_2;
-			break;
-		}
-		if (mwdma_mask & 0x02) {
-			speed = XFER_MW_DMA_1;
-			break;
-		}
-		if (mwdma_mask & 0x01) {
-			speed = XFER_MW_DMA_0;
-			break;
-		}
-
-		swdma_mask = id->dma_1word & hwif->swdma_mask;
-
-		if (swdma_mask & 0x04) {
-			speed = XFER_SW_DMA_2;
-			break;
-		}
-		if (swdma_mask & 0x02) {
-			speed = XFER_SW_DMA_1;
-			break;
-		}
-		if (swdma_mask & 0x01) {
-			speed = XFER_SW_DMA_0;
-			break;
-		}
-	}
-
-	return speed;
-}
-EXPORT_SYMBOL(ide_dma_speed);
-
-
-/**
- *	ide_rate_filter		-	return best speed for mode
- *	@mode: modes available
+ *	ide_rate_filter		-	filter transfer mode
+ *	@drive: IDE device
  *	@speed: desired speed
  *
- *	Given the available DMA/UDMA mode this function returns
+ *	Given the available transfer modes this function returns
  *	the best available speed at or below the speed requested.
+ *
+ *	FIXME: filter also PIO/SWDMA/MWDMA modes
  */
 
-u8 ide_rate_filter (u8 mode, u8 speed) 
+u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
 {
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	static u8 speed_max[] = {
-		XFER_MW_DMA_2, XFER_UDMA_2, XFER_UDMA_4,
-		XFER_UDMA_5, XFER_UDMA_6
-	};
+	ide_hwif_t *hwif = drive->hwif;
+	u8 mask = hwif->ultra_mask, mode = XFER_MW_DMA_2;
+
+	if (hwif->filter_udma_mask)
+		mask = hwif->filter_udma_mask(drive);
+
+	if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
+		mask &= 0x07;
+
+	if (mask)
+		mode = fls(mask) - 1 + XFER_UDMA_0;
 
 //	printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed);
 
-	/* So that we remember to update this if new modes appear */
-	BUG_ON(mode > 4);
-	return min(speed, speed_max[mode]);
+	return min(speed, mode);
 #else /* !CONFIG_BLK_DEV_IDEDMA */
 	return min(speed, (u8)XFER_PIO_4);
 #endif /* CONFIG_BLK_DEV_IDEDMA */
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -483,6 +483,7 @@ static void ide_hwif_restore(ide_hwif_t 
 
 	hwif->tuneproc			= tmp_hwif->tuneproc;
 	hwif->speedproc			= tmp_hwif->speedproc;
+	hwif->filter_udma_mask		= tmp_hwif->filter_udma_mask;
 	hwif->selectproc		= tmp_hwif->selectproc;
 	hwif->reset_poll		= tmp_hwif->reset_poll;
 	hwif->pre_reset			= tmp_hwif->pre_reset;
Index: b/drivers/ide/pci/aec62xx.c
===================================================================
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -86,38 +86,12 @@ static u8 pci_bus_clock_list_ultra (u8 s
 	return chipset_table->ultra_settings;
 }
 
-static u8 aec62xx_ratemask (ide_drive_t *drive)
-{
-	ide_hwif_t *hwif	= HWIF(drive);
-	u8 mode;
-
-	switch(hwif->pci_dev->device) {
-		case PCI_DEVICE_ID_ARTOP_ATP865:
-		case PCI_DEVICE_ID_ARTOP_ATP865R:
-			mode = (inb(hwif->channel ?
-				    hwif->mate->dma_status :
-				    hwif->dma_status) & 0x10) ? 4 : 3;
-			break;
-		case PCI_DEVICE_ID_ARTOP_ATP860:
-		case PCI_DEVICE_ID_ARTOP_ATP860R:
-			mode = 2;
-			break;
-		case PCI_DEVICE_ID_ARTOP_ATP850UF:
-		default:
-			return 1;
-	}
-
-	if (!eighty_ninty_three(drive))
-		mode = min(mode, (u8)1);
-	return mode;
-}
-
 static int aec6210_tune_chipset (ide_drive_t *drive, u8 xferspeed)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= hwif->pci_dev;
 	u16 d_conf		= 0;
-	u8 speed	= ide_rate_filter(aec62xx_ratemask(drive), xferspeed);
+	u8 speed		= ide_rate_filter(drive, xferspeed);
 	u8 ultra = 0, ultra_conf = 0;
 	u8 tmp0 = 0, tmp1 = 0, tmp2 = 0;
 	unsigned long flags;
@@ -144,7 +118,7 @@ static int aec6260_tune_chipset (ide_dri
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= hwif->pci_dev;
-	u8 speed	= ide_rate_filter(aec62xx_ratemask(drive), xferspeed);
+	u8 speed	= ide_rate_filter(drive, xferspeed);
 	u8 unit		= (drive->select.b.unit & 0x01);
 	u8 tmp1 = 0, tmp2 = 0;
 	u8 ultra = 0, drive_conf = 0, ultra_conf = 0;
@@ -182,7 +156,7 @@ static int aec62xx_tune_chipset (ide_dri
 
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
-	u8 speed = ide_dma_speed(drive, aec62xx_ratemask(drive));	
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!(speed))
 		return 0;
Index: b/drivers/ide/pci/alim15x3.c
===================================================================
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -359,74 +359,31 @@ static void ali15x3_tune_drive (ide_driv
 }
 
 /**
- *	ali15x3_can_ultra	-	check for ultra DMA support
- *	@drive: drive to do the check
+ *	ali_filter_udma_mask	-	compute UDMA mask
+ *	@drive: IDE device
  *
- *	Check the drive and controller revisions. Return 0 if UDMA is
- *	not available, or 1 if UDMA can be used. The actual rules for
- *	the ALi are
+ *	Return available UDMA modes.
+ *
+ *	The actual rules for the ALi are:
  *		No UDMA on revisions <= 0x20
  *		Disk only for revisions < 0xC2
  *		Not WDC drives for revisions < 0xC2
  *
  *	FIXME: WDC ifdef needs to die
  */
- 
-static u8 ali15x3_can_ultra (ide_drive_t *drive)
-{
-#ifndef CONFIG_WDC_ALI15X3
-	struct hd_driveid *id	= drive->id;
-#endif /* CONFIG_WDC_ALI15X3 */
-
-	if (m5229_revision <= 0x20) {
-		return 0;
-	} else if ((m5229_revision < 0xC2) &&
-#ifndef CONFIG_WDC_ALI15X3
-		   ((chip_is_1543c_e && strstr(id->model, "WDC ")) ||
-		    (drive->media!=ide_disk))) {
-#else /* CONFIG_WDC_ALI15X3 */
-		   (drive->media!=ide_disk)) {
-#endif /* CONFIG_WDC_ALI15X3 */
-		return 0;
-	} else {
-		return 1;
-	}
-}
 
-/**
- *	ali15x3_ratemask	-	generate DMA mode list
- *	@drive: drive to compute against
- *
- *	Generate a list of the available DMA modes for the drive. 
- *	FIXME: this function contains lots of bogus masking we can dump
- *
- *	Return the highest available mode (UDMA33, UDMA66, UDMA100,..)
- */
- 
-static u8 ali15x3_ratemask (ide_drive_t *drive)
+static u8 ali_filter_udma_mask(ide_drive_t *drive)
 {
-	u8 mode = 0, can_ultra	= ali15x3_can_ultra(drive);
-
-	if (m5229_revision > 0xC4 && can_ultra) {
-		mode = 4;
-	} else if (m5229_revision == 0xC4 && can_ultra) {
-		mode = 3;
-	} else if (m5229_revision >= 0xC2 && can_ultra) {
-		mode = 2;
-	} else if (can_ultra) {
-		return 1;
-	} else {
-		return 0;
+	if (m5229_revision > 0x20 && m5229_revision < 0xC2) {
+		if (drive->media != ide_disk)
+			return 0;
+#ifndef CONFIG_WDC_ALI15X3
+		if (chip_is_1543c_e && strstr(drive->id->model, "WDC "))
+			return 0;
+#endif
 	}
 
-	/*
-	 *	If the drive sees no suitable cable then UDMA 33
-	 *	is the highest permitted mode
-	 */
-	 
-	if (!eighty_ninty_three(drive))
-		mode = min(mode, (u8)1);
-	return mode;
+	return drive->hwif->ultra_mask;
 }
 
 /**
@@ -442,7 +399,7 @@ static int ali15x3_tune_chipset (ide_dri
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= hwif->pci_dev;
-	u8 speed		= ide_rate_filter(ali15x3_ratemask(drive), xferspeed);
+	u8 speed		= ide_rate_filter(drive, xferspeed);
 	u8 speed1		= speed;
 	u8 unit			= (drive->select.b.unit & 0x01);
 	u8 tmpbyte		= 0x00;
@@ -492,7 +449,7 @@ static int ali15x3_tune_chipset (ide_dri
  
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
-	u8 speed = ide_dma_speed(drive, ali15x3_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!(speed))
 		return 0;
@@ -753,6 +710,7 @@ static void __devinit init_hwif_common_a
 	hwif->autodma = 0;
 	hwif->tuneproc = &ali15x3_tune_drive;
 	hwif->speedproc = &ali15x3_tune_chipset;
+	hwif->filter_udma_mask = &ali_filter_udma_mask;
 
 	/* don't use LBA48 DMA on ALi devices before rev 0xC5 */
 	hwif->no_lba48_dma = (m5229_revision <= 0xC4) ? 1 : 0;
Index: b/drivers/ide/pci/atiixp.c
===================================================================
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -49,22 +49,6 @@ static int save_mdma_mode[4];
 static DEFINE_SPINLOCK(atiixp_lock);
 
 /**
- *	atiixp_ratemask		-	compute rate mask for ATIIXP IDE
- *	@drive: IDE drive to compute for
- *
- *	Returns the available modes for the ATIIXP IDE controller.
- */
-
-static u8 atiixp_ratemask(ide_drive_t *drive)
-{
-	u8 mode = 3;
-
-	if (!eighty_ninty_three(drive))
-		mode = min(mode, (u8)1);
-	return mode;
-}
-
-/**
  *	atiixp_dma_2_pio		-	return the PIO mode matching DMA
  *	@xfer_rate: transfer speed
  *
@@ -189,7 +173,7 @@ static int atiixp_speedproc(ide_drive_t 
 	u16 tmp16;
 	u8 speed, pio;
 
-	speed = ide_rate_filter(atiixp_ratemask(drive), xferspeed);
+	speed = ide_rate_filter(drive, xferspeed);
 
 	spin_lock_irqsave(&atiixp_lock, flags);
 
@@ -233,7 +217,7 @@ static int atiixp_speedproc(ide_drive_t 
 
 static int atiixp_config_drive_for_dma(ide_drive_t *drive)
 {
-	u8 speed = ide_dma_speed(drive, atiixp_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!speed)
 		return 0;
Index: b/drivers/ide/pci/cmd64x.c
===================================================================
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -338,55 +338,6 @@ static void cmd64x_tuneproc (ide_drive_t
 		setup_count, active_count, recovery_count);
 }
 
-static u8 cmd64x_ratemask (ide_drive_t *drive)
-{
-	struct pci_dev *dev	= HWIF(drive)->pci_dev;
-	u8 mode = 0;
-
-	switch(dev->device) {
-		case PCI_DEVICE_ID_CMD_649:
-			mode = 3;
-			break;
-		case PCI_DEVICE_ID_CMD_648:
-			mode = 2;
-			break;
-		case PCI_DEVICE_ID_CMD_643:
-			return 0;
-
-		case PCI_DEVICE_ID_CMD_646:
-		{
-			unsigned int class_rev	= 0;
-			pci_read_config_dword(dev,
-				PCI_CLASS_REVISION, &class_rev);
-			class_rev &= 0xff;
-		/*
-		 * UltraDMA only supported on PCI646U and PCI646U2, which
-		 * correspond to revisions 0x03, 0x05 and 0x07 respectively.
-		 * Actually, although the CMD tech support people won't
-		 * tell me the details, the 0x03 revision cannot support
-		 * UDMA correctly without hardware modifications, and even
-		 * then it only works with Quantum disks due to some
-		 * hold time assumptions in the 646U part which are fixed
-		 * in the 646U2.
-		 *
-		 * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
-		 */
-			switch(class_rev) {
-				case 0x07:
-				case 0x05:
-					return 1;
-				case 0x03:
-				case 0x01:
-				default:
-					return 0;
-			}
-		}
-	}
-	if (!eighty_ninty_three(drive))
-		mode = min(mode, (u8)1);
-	return mode;
-}
-
 static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, u8 set_speed)
 {
 	u8 speed	= 0x00;
@@ -412,7 +363,7 @@ static int cmd64x_tune_chipset (ide_driv
 	u8 regU = 0, pciU	= (hwif->channel) ? UDIDETCR1 : UDIDETCR0;
 	u8 regD = 0, pciD	= (hwif->channel) ? BMIDESR1 : BMIDESR0;
 
-	u8 speed	= ide_rate_filter(cmd64x_ratemask(drive), xferspeed);
+	u8 speed = ide_rate_filter(drive, xferspeed);
 
 	if (speed > XFER_PIO_4) {
 		(void) pci_read_config_byte(dev, pciD, &regD);
@@ -459,7 +410,7 @@ static int cmd64x_tune_chipset (ide_driv
 
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
-	u8 speed	= ide_dma_speed(drive, cmd64x_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	config_chipset_for_pio(drive, !speed);
 
@@ -696,6 +647,19 @@ static void __devinit init_hwif_cmd64x(i
 
 	if (dev->device == PCI_DEVICE_ID_CMD_643)
 		hwif->ultra_mask = 0x00;
+
+	/*
+	 * UltraDMA only supported on PCI646U and PCI646U2, which
+	 * correspond to revisions 0x03, 0x05 and 0x07 respectively.
+	 * Actually, although the CMD tech support people won't
+	 * tell me the details, the 0x03 revision cannot support
+	 * UDMA correctly without hardware modifications, and even
+	 * then it only works with Quantum disks due to some
+	 * hold time assumptions in the 646U part which are fixed
+	 * in the 646U2.
+	 *
+	 * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
+	 */
 	if (dev->device == PCI_DEVICE_ID_CMD_646)
 		hwif->ultra_mask =
 			(class_rev == 0x05 || class_rev == 0x07) ? 0x07 : 0x00;
Index: b/drivers/ide/pci/cs5535.c
===================================================================
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -127,20 +127,6 @@ static void cs5535_set_speed(ide_drive_t
 	}
 }
 
-static u8 cs5535_ratemask(ide_drive_t *drive)
-{
-	/* eighty93 will return 1 if it's 80core and capable of
-	exceeding udma2, 0 otherwise. we need ratemask to set
-	the max speed and if we can > udma2 then we return 2
-	which selects speed_max as udma4 which is the 5535's max
-	speed, and 1 selects udma2 which is the max for 40c */
-	if (!eighty_ninty_three(drive))
-		return 1;
-
-	return 2;
-}
-
-
 /****
  *	cs5535_set_drive         -     Configure the drive to the new speed
  *	@drive: Drive to set up
@@ -151,7 +137,7 @@ static u8 cs5535_ratemask(ide_drive_t *d
  */
 static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
 {
-	speed = ide_rate_filter(cs5535_ratemask(drive), speed);
+	speed = ide_rate_filter(drive, speed);
 	ide_config_drive_speed(drive, speed);
 	cs5535_set_speed(drive, speed);
 
@@ -180,9 +166,7 @@ static void cs5535_tuneproc(ide_drive_t 
 
 static int cs5535_config_drive_for_dma(ide_drive_t *drive)
 {
-	u8 speed;
-
-	speed = ide_dma_speed(drive, cs5535_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	/* If no DMA speed was available then let dma_check hit pio */
 	if (!speed) {
Index: b/drivers/ide/pci/hpt34x.c
===================================================================
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -43,15 +43,10 @@
 
 #define HPT343_DEBUG_DRIVE_INFO		0
 
-static u8 hpt34x_ratemask (ide_drive_t *drive)
-{
-	return 1;
-}
-
 static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
 {
 	struct pci_dev *dev	= HWIF(drive)->pci_dev;
-	u8 speed	= ide_rate_filter(hpt34x_ratemask(drive), xferspeed);
+	u8 speed = ide_rate_filter(drive, xferspeed);
 	u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
 	u8			hi_speed, lo_speed;
 
@@ -98,7 +93,7 @@ static void hpt34x_tune_drive (ide_drive
 
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
-	u8 speed = ide_dma_speed(drive, hpt34x_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!(speed))
 		return 0;
Index: b/drivers/ide/pci/hpt366.c
===================================================================
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -513,43 +513,31 @@ static int check_in_drive_list(ide_drive
 	return 0;
 }
 
-static u8 hpt3xx_ratemask(ide_drive_t *drive)
-{
-	struct hpt_info *info	= pci_get_drvdata(HWIF(drive)->pci_dev);
-	u8 mode			= info->max_mode;
-
-	if (!eighty_ninty_three(drive) && mode)
-		mode = min(mode, (u8)1);
-	return mode;
-}
-
 /*
  *	Note for the future; the SATA hpt37x we must set
  *	either PIO or UDMA modes 0,4,5
  */
- 
-static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed)
+
+static u8 hpt3xx_filter_udma_mask(ide_drive_t *drive)
 {
 	struct hpt_info *info	= pci_get_drvdata(HWIF(drive)->pci_dev);
 	u8 chip_type		= info->chip_type;
-	u8 mode			= hpt3xx_ratemask(drive);
-
-	if (drive->media != ide_disk)
-		return min(speed, (u8)XFER_PIO_4);
+	u8 mode			= info->max_mode;
+	u8 mask;
 
 	switch (mode) {
 		case 0x04:
-			speed = min_t(u8, speed, XFER_UDMA_6);
+			mask = 0x7f;
 			break;
 		case 0x03:
-			speed = min_t(u8, speed, XFER_UDMA_5);
+			mask = 0x3f;
 			if (chip_type >= HPT374)
 				break;
 			if (!check_in_drive_list(drive, bad_ata100_5))
 				goto check_bad_ata33;
 			/* fall thru */
 		case 0x02:
-			speed = min_t(u8, speed, XFER_UDMA_4);
+			mask = 0x1f;
 
 			/*
 			 * CHECK ME, Does this need to be changed to HPT374 ??
@@ -560,13 +548,13 @@ static u8 hpt3xx_ratefilter(ide_drive_t 
 			    !check_in_drive_list(drive, bad_ata66_4))
 				goto check_bad_ata33;
 
-			speed = min_t(u8, speed, XFER_UDMA_3);
+			mask = 0x0f;
 			if (HPT366_ALLOW_ATA66_3 &&
 			    !check_in_drive_list(drive, bad_ata66_3))
 				goto check_bad_ata33;
 			/* fall thru */
 		case 0x01:
-			speed = min_t(u8, speed, XFER_UDMA_2);
+			mask = 0x07;
 
 		check_bad_ata33:
 			if (chip_type >= HPT370A)
@@ -576,10 +564,10 @@ static u8 hpt3xx_ratefilter(ide_drive_t 
 			/* fall thru */
 		case 0x00:
 		default:
-			speed = min_t(u8, speed, XFER_MW_DMA_2);
+			mask = 0x00;
 			break;
 	}
-	return speed;
+	return mask;
 }
 
 static u32 get_speed_setting(u8 speed, struct hpt_info *info)
@@ -607,12 +595,19 @@ static int hpt36x_tune_chipset(ide_drive
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev  *dev	= hwif->pci_dev;
 	struct hpt_info	*info	= pci_get_drvdata(dev);
-	u8  speed		= hpt3xx_ratefilter(drive, xferspeed);
+	u8  speed		= ide_rate_filter(drive, xferspeed);
 	u8  itr_addr		= drive->dn ? 0x44 : 0x40;
-	u32 itr_mask		= speed < XFER_MW_DMA_0 ? 0x30070000 :
-				 (speed < XFER_UDMA_0   ? 0xc0070000 : 0xc03800ff);
-	u32 new_itr		= get_speed_setting(speed, info);
 	u32 old_itr		= 0;
+	u32 itr_mask, new_itr;
+
+	/* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
+	if (drive->media != ide_disk)
+		speed = min_t(u8, speed, XFER_PIO_4);
+
+	itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 :
+		  (speed < XFER_UDMA_0   ? 0xc0070000 : 0xc03800ff);
+
+	new_itr = get_speed_setting(speed, info);
 
 	/*
 	 * Disable on-chip PIO FIFO/buffer (and PIO MST mode as well)
@@ -632,12 +627,19 @@ static int hpt37x_tune_chipset(ide_drive
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev  *dev	= hwif->pci_dev;
 	struct hpt_info	*info	= pci_get_drvdata(dev);
-	u8  speed		= hpt3xx_ratefilter(drive, xferspeed);
+	u8  speed		= ide_rate_filter(drive, xferspeed);
 	u8  itr_addr		= 0x40 + (drive->dn * 4);
-	u32 itr_mask		= speed < XFER_MW_DMA_0 ? 0x303c0000 :
-				 (speed < XFER_UDMA_0   ? 0xc03c0000 : 0xc1c001ff);
-	u32 new_itr		= get_speed_setting(speed, info);
 	u32 old_itr		= 0;
+	u32 itr_mask, new_itr;
+
+	/* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
+	if (drive->media != ide_disk)
+		speed = min_t(u8, speed, XFER_PIO_4);
+
+	itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 :
+		  (speed < XFER_UDMA_0   ? 0xc03c0000 : 0xc1c001ff);
+
+	new_itr = get_speed_setting(speed, info);
 
 	pci_read_config_dword(dev, itr_addr, &old_itr);
 	new_itr = (new_itr & ~itr_mask) | (old_itr & itr_mask);
@@ -675,7 +677,7 @@ static void hpt3xx_tune_drive(ide_drive_
  */
 static int config_chipset_for_dma(ide_drive_t *drive)
 {
-	u8 speed = ide_dma_speed(drive, hpt3xx_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!speed)
 		return 0;
@@ -1270,6 +1272,7 @@ static void __devinit init_hwif_hpt366(i
 	hwif->intrproc			= &hpt3xx_intrproc;
 	hwif->maskproc			= &hpt3xx_maskproc;
 	hwif->busproc			= &hpt3xx_busproc;
+	hwif->filter_udma_mask		= &hpt3xx_filter_udma_mask;
 
 	/*
 	 * HPT3xxN chips have some complications:
Index: b/drivers/ide/pci/it8213.c
===================================================================
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -17,22 +17,6 @@
 
 #include <asm/io.h>
 
-/*
- *	it8213_ratemask	-	Compute available modes
- *	@drive: IDE drive
- *
- *	Compute the available speeds for the devices on the interface. This
- *	is all modes to ATA133 clipped by drive cable setup.
- */
-
-static u8 it8213_ratemask (ide_drive_t *drive)
-{
-	u8 mode	= 4;
-	if (!eighty_ninty_three(drive))
-		mode = min_t(u8, mode, 1);
-	return mode;
-}
-
 /**
  *	it8213_dma_2_pio		-	return the PIO mode matching DMA
  *	@xfer_rate: transfer speed
@@ -145,7 +129,7 @@ static int it8213_tune_chipset (ide_driv
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= hwif->pci_dev;
 	u8 maslave		= 0x40;
-	u8 speed		= ide_rate_filter(it8213_ratemask(drive), xferspeed);
+	u8 speed		= ide_rate_filter(drive, xferspeed);
 	int a_speed		= 3 << (drive->dn * 4);
 	int u_flag		= 1 << drive->dn;
 	int v_flag		= 0x01 << drive->dn;
@@ -222,7 +206,7 @@ static int it8213_tune_chipset (ide_driv
 
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
-	u8 speed = ide_dma_speed(drive, it8213_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!speed)
 		return 0;
Index: b/drivers/ide/pci/it821x.c
===================================================================
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -224,22 +224,6 @@ static void it821x_clock_strategy(ide_dr
 }
 
 /**
- *	it821x_ratemask	-	Compute available modes
- *	@drive: IDE drive
- *
- *	Compute the available speeds for the devices on the interface. This
- *	is all modes to ATA133 clipped by drive cable setup.
- */
-
-static u8 it821x_ratemask (ide_drive_t *drive)
-{
-	u8 mode	= 4;
-	if (!eighty_ninty_three(drive))
-		mode = min(mode, (u8)1);
-	return mode;
-}
-
-/**
  *	it821x_tuneproc	-	tune a drive
  *	@drive: drive to tune
  *	@mode_wanted: the target operating mode
@@ -448,7 +432,7 @@ static int it821x_tune_chipset (ide_driv
 
 	ide_hwif_t *hwif	= drive->hwif;
 	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
-	u8 speed		= ide_rate_filter(it821x_ratemask(drive), xferspeed);
+	u8 speed		= ide_rate_filter(drive, xferspeed);
 
 	if(!itdev->smart) {
 		switch(speed) {
@@ -496,7 +480,7 @@ static int it821x_tune_chipset (ide_driv
 
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
-	u8 speed	= ide_dma_speed(drive, it821x_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (speed) {
 		config_it821x_chipset_for_pio(drive, 0);
Index: b/drivers/ide/pci/jmicron.c
===================================================================
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -22,22 +22,6 @@ typedef enum {
 } port_type;
 
 /**
- *	jmicron_ratemask	-	Compute available modes
- *	@drive: IDE drive
- *
- *	Compute the available speeds for the devices on the interface. This
- *	is all modes to ATA133 clipped by drive cable setup.
- */
-
-static u8 jmicron_ratemask(ide_drive_t *drive)
-{
-	u8 mode	= 4;
-	if (!eighty_ninty_three(drive))
-		mode = min(mode, (u8)1);
-	return mode;
-}
-
-/**
  *	ata66_jmicron		-	Cable check
  *	@hwif: IDE port
  *
@@ -129,8 +113,7 @@ static void config_jmicron_chipset_for_p
 
 static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed)
 {
-
-	u8 speed		= ide_rate_filter(jmicron_ratemask(drive), xferspeed);
+	u8 speed = ide_rate_filter(drive, xferspeed);
 
 	return ide_config_drive_speed(drive, speed);
 }
@@ -145,7 +128,7 @@ static int jmicron_tune_chipset (ide_dri
 
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
-	u8 speed	= ide_dma_speed(drive, jmicron_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!speed)
 		return 0;
Index: b/drivers/ide/pci/pdc202xx_new.c
===================================================================
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -82,16 +82,6 @@ static u8 max_dma_rate(struct pci_dev *p
 	return mode;
 }
 
-static u8 pdcnew_ratemask(ide_drive_t *drive)
-{
-	u8 mode = max_dma_rate(HWIF(drive)->pci_dev);
-
-	if (!eighty_ninty_three(drive))
-		mode = min_t(u8, mode, 1);
-
-	return	mode;
-}
-
 /**
  * get_indexed_reg - Get indexed register
  * @hwif: for the port address
@@ -164,7 +154,7 @@ static int pdcnew_tune_chipset(ide_drive
 	u8 adj			= (drive->dn & 1) ? 0x08 : 0x00;
 	int			err;
 
-	speed = ide_rate_filter(pdcnew_ratemask(drive), speed);
+	speed = ide_rate_filter(drive, speed);
 
 	/*
 	 * Issue SETFEATURES_XFER to the drive first. PDC202xx hardware will
@@ -270,7 +260,7 @@ static int config_chipset_for_dma(ide_dr
 		set_indexed_reg(hwif, 0x13 + adj, tmp | 0x03);
 	}
 
-	speed = ide_dma_speed(drive, pdcnew_ratemask(drive));
+	speed = ide_max_dma_mode(drive);
 
 	if (!speed)
 		return 0;
Index: b/drivers/ide/pci/pdc202xx_old.c
===================================================================
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -100,35 +100,12 @@ static const char *pdc_quirk_drives[] = 
 #define	MC1		0x02	/* DMA"C" timing */
 #define	MC0		0x01	/* DMA"C" timing */
 
-static u8 pdc202xx_ratemask (ide_drive_t *drive)
-{
-	u8 mode;
-
-	switch(HWIF(drive)->pci_dev->device) {
-		case PCI_DEVICE_ID_PROMISE_20267:
-		case PCI_DEVICE_ID_PROMISE_20265:
-			mode = 3;
-			break;
-		case PCI_DEVICE_ID_PROMISE_20263:
-		case PCI_DEVICE_ID_PROMISE_20262:
-			mode = 2;
-			break;
-		case PCI_DEVICE_ID_PROMISE_20246:
-			return 1;
-		default:
-			return 0;
-	}
-	if (!eighty_ninty_three(drive))
-		mode = min(mode, (u8)1);
-	return mode;
-}
-
 static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= hwif->pci_dev;
 	u8 drive_pci		= 0x60 + (drive->dn << 2);
-	u8 speed	= ide_rate_filter(pdc202xx_ratemask(drive), xferspeed);
+	u8 speed		= ide_rate_filter(drive, xferspeed);
 
 	u32			drive_conf;
 	u8			AP, BP, CP, DP;
@@ -318,7 +295,7 @@ chipset_is_set:
 	if (drive->media == ide_disk)	/* PREFETCH_EN */
 		pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
 
-	speed = ide_dma_speed(drive, pdc202xx_ratemask(drive));
+	speed = ide_max_dma_mode(drive);
 
 	if (!(speed)) {
 		/* restore original pci-config space */
Index: b/drivers/ide/pci/piix.c
===================================================================
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -106,68 +106,6 @@
 static int no_piix_dma;
 
 /**
- *	piix_ratemask		-	compute rate mask for PIIX IDE
- *	@drive: IDE drive to compute for
- *
- *	Returns the available modes for the PIIX IDE controller.
- */
- 
-static u8 piix_ratemask (ide_drive_t *drive)
-{
-	struct pci_dev *dev	= HWIF(drive)->pci_dev;
-	u8 mode;
-
-	switch(dev->device) {
-		case PCI_DEVICE_ID_INTEL_82801EB_1:
-			mode = 3;
-			break;
-		/* UDMA 100 capable */
-		case PCI_DEVICE_ID_INTEL_82801BA_8:
-		case PCI_DEVICE_ID_INTEL_82801BA_9:
-		case PCI_DEVICE_ID_INTEL_82801CA_10:
-		case PCI_DEVICE_ID_INTEL_82801CA_11:
-		case PCI_DEVICE_ID_INTEL_82801E_11:
-		case PCI_DEVICE_ID_INTEL_82801DB_1:
-		case PCI_DEVICE_ID_INTEL_82801DB_10:
-		case PCI_DEVICE_ID_INTEL_82801DB_11:
-		case PCI_DEVICE_ID_INTEL_82801EB_11:
-		case PCI_DEVICE_ID_INTEL_ESB_2:
-		case PCI_DEVICE_ID_INTEL_ICH6_19:
-		case PCI_DEVICE_ID_INTEL_ICH7_21:
-		case PCI_DEVICE_ID_INTEL_ESB2_18:
-		case PCI_DEVICE_ID_INTEL_ICH8_6:
-			mode = 3;
-			break;
-		/* UDMA 66 capable */
-		case PCI_DEVICE_ID_INTEL_82801AA_1:
-		case PCI_DEVICE_ID_INTEL_82372FB_1:
-			mode = 2;
-			break;
-		/* UDMA 33 capable */
-		case PCI_DEVICE_ID_INTEL_82371AB:
-		case PCI_DEVICE_ID_INTEL_82443MX_1:
-		case PCI_DEVICE_ID_INTEL_82451NX:
-		case PCI_DEVICE_ID_INTEL_82801AB_1:
-			return 1;
-		/* Non UDMA capable (MWDMA2) */
-		case PCI_DEVICE_ID_INTEL_82371SB_1:
-		case PCI_DEVICE_ID_INTEL_82371FB_1:
-		case PCI_DEVICE_ID_INTEL_82371FB_0:
-		case PCI_DEVICE_ID_INTEL_82371MX:
-		default:
-			return 0;
-	}
-	
-	/*
-	 *	If we are UDMA66 capable fall back to UDMA33 
-	 *	if the drive cannot see an 80pin cable.
-	 */
-	if (!eighty_ninty_three(drive))
-		mode = min_t(u8, mode, 1);
-	return mode;
-}
-
-/**
  *	piix_dma_2_pio		-	return the PIO mode matching DMA
  *	@xfer_rate: transfer speed
  *
@@ -288,7 +226,7 @@ static int piix_tune_chipset (ide_drive_
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= hwif->pci_dev;
 	u8 maslave		= hwif->channel ? 0x42 : 0x40;
-	u8 speed		= ide_rate_filter(piix_ratemask(drive), xferspeed);
+	u8 speed		= ide_rate_filter(drive, xferspeed);
 	int a_speed		= 3 << (drive->dn * 4);
 	int u_flag		= 1 << drive->dn;
 	int v_flag		= 0x01 << drive->dn;
@@ -363,7 +301,7 @@ static int piix_tune_chipset (ide_drive_
  
 static int piix_config_drive_for_dma (ide_drive_t *drive)
 {
-	u8 speed = ide_dma_speed(drive, piix_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	/*
 	 * If no DMA speed was available or the chipset has DMA bugs
Index: b/drivers/ide/pci/serverworks.c
===================================================================
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -65,16 +65,16 @@ static int check_in_drive_lists (ide_dri
 	return 0;
 }
 
-static u8 svwks_ratemask (ide_drive_t *drive)
+static u8 svwks_filter_udma_mask(ide_drive_t *drive)
 {
 	struct pci_dev *dev     = HWIF(drive)->pci_dev;
-	u8 mode = 0;
+	u8 mask = 0;
 
 	if (!svwks_revision)
 		pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
 
 	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
-		return 2;
+		return 0x1f;
 	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
 		u32 reg = 0;
 		if (isa_dev)
@@ -86,25 +86,31 @@ static u8 svwks_ratemask (ide_drive_t *d
 		if(drive->media == ide_disk)
 			return 0;
 		/* Check the OSB4 DMA33 enable bit */
-		return ((reg & 0x00004000) == 0x00004000) ? 1 : 0;
+		return ((reg & 0x00004000) == 0x00004000) ? 0x07 : 0;
 	} else if (svwks_revision < SVWKS_CSB5_REVISION_NEW) {
-		return 1;
+		return 0x07;
 	} else if (svwks_revision >= SVWKS_CSB5_REVISION_NEW) {
-		u8 btr = 0;
+		u8 btr = 0, mode;
 		pci_read_config_byte(dev, 0x5A, &btr);
 		mode = btr & 0x3;
-		if (!eighty_ninty_three(drive))
-			mode = min(mode, (u8)1);
+
 		/* If someone decides to do UDMA133 on CSB5 the same
 		   issue will bite so be inclusive */
 		if (mode > 2 && check_in_drive_lists(drive, svwks_bad_ata100))
 			mode = 2;
+
+		switch(mode) {
+		case 2:	 mask = 0x1f; break;
+		case 1:	 mask = 0x07; break;
+		default: mask = 0x00; break;
+		}
 	}
 	if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
 	     (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) &&
 	    (!(PCI_FUNC(dev->devfn) & 1)))
-		mode = 2;
-	return mode;
+		mask = 0x1f;
+
+	return mask;
 }
 
 static u8 svwks_csb_check (struct pci_dev *dev)
@@ -141,7 +147,7 @@ static int svwks_tune_chipset (ide_drive
 	if (xferspeed == 255)	/* PIO auto-tuning */
 		speed = XFER_PIO_0 + pio;
 	else
-		speed = ide_rate_filter(svwks_ratemask(drive), xferspeed);
+		speed = ide_rate_filter(drive, xferspeed);
 
 	/* If we are about to put a disk into UDMA mode we screwed up.
 	   Our code assumes we never _ever_ do this on an OSB4 */
@@ -304,7 +310,7 @@ static void svwks_tune_drive (ide_drive_
 
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
-	u8 speed = ide_dma_speed(drive, svwks_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!(speed))
 		speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
@@ -500,6 +506,7 @@ static void __devinit init_hwif_svwks (i
 
 	hwif->tuneproc = &svwks_tune_drive;
 	hwif->speedproc = &svwks_tune_chipset;
+	hwif->filter_udma_mask = &svwks_filter_udma_mask;
 
 	hwif->atapi_dma = 1;
 
Index: b/drivers/ide/pci/siimage.c
===================================================================
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -116,45 +116,41 @@ static inline unsigned long siimage_seld
 }
 
 /**
- *	siimage_ratemask	-	Compute available modes
- *	@drive: IDE drive
+ *	sil_filter_udma_mask	-	compute UDMA mask
+ *	@drive: IDE device
+ *
+ *	Compute the available UDMA speeds for the device on the interface.
  *
- *	Compute the available speeds for the devices on the interface.
  *	For the CMD680 this depends on the clocking mode (scsc), for the
- *	SI3312 SATA controller life is a bit simpler. Enforce UDMA33
- *	as a limit if there is no 80pin cable present.
+ *	SI3112 SATA controller life is a bit simpler.
  */
- 
-static byte siimage_ratemask (ide_drive_t *drive)
+
+static u8 sil_filter_udma_mask(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	u8 mode	= 0, scsc = 0;
+	ide_hwif_t *hwif = drive->hwif;
 	unsigned long base = (unsigned long) hwif->hwif_data;
+	u8 mask = 0, scsc = 0;
 
 	if (hwif->mmio)
 		scsc = hwif->INB(base + 0x4A);
 	else
 		pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
 
-	if(is_sata(hwif))
-	{
-		if(strstr(drive->id->model, "Maxtor"))
-			return 3;
-		return 4;
+	if (is_sata(hwif)) {
+		mask = strstr(drive->id->model, "Maxtor") ? 0x3f : 0x7f;
+		goto out;
 	}
-	
+
 	if ((scsc & 0x30) == 0x10)	/* 133 */
-		mode = 4;
+		mask = 0x7f;
 	else if ((scsc & 0x30) == 0x20)	/* 2xPCI */
-		mode = 4;
+		mask = 0x7f;
 	else if ((scsc & 0x30) == 0x00)	/* 100 */
-		mode = 3;
+		mask = 0x3f;
 	else 	/* Disabled ? */
 		BUG();
-
-	if (!eighty_ninty_three(drive))
-		mode = min(mode, (u8)1);
-	return mode;
+out:
+	return mask;
 }
 
 /**
@@ -307,7 +303,7 @@ static int siimage_tune_chipset (ide_dri
 	ide_hwif_t *hwif	= HWIF(drive);
 	u16 ultra = 0, multi	= 0;
 	u8 mode = 0, unit	= drive->select.b.unit;
-	u8 speed		= ide_rate_filter(siimage_ratemask(drive), xferspeed);
+	u8 speed		= ide_rate_filter(drive, xferspeed);
 	unsigned long base	= (unsigned long)hwif->hwif_data;
 	u8 scsc = 0, addr_mask	= ((hwif->channel) ?
 				    ((hwif->mmio) ? 0xF4 : 0x84) :
@@ -390,7 +386,7 @@ static int siimage_tune_chipset (ide_dri
  
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
-	u8 speed	= ide_dma_speed(drive, siimage_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	config_chipset_for_pio(drive, !speed);
 
@@ -992,6 +988,7 @@ static void __devinit init_hwif_siimage(
 	hwif->tuneproc	= &siimage_tuneproc;
 	hwif->reset_poll = &siimage_reset_poll;
 	hwif->pre_reset = &siimage_pre_reset;
+	hwif->filter_udma_mask = &sil_filter_udma_mask;
 
 	if(is_sata(hwif)) {
 		static int first = 1;
Index: b/drivers/ide/pci/sis5513.c
===================================================================
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -428,16 +428,6 @@ static int sis_get_info (char *buffer, c
 }
 #endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
 
-static u8 sis5513_ratemask (ide_drive_t *drive)
-{
-	u8 rates[] = { 0, 0, 1, 2, 3, 3, 4, 4 };
-	u8 mode = rates[chipset_family];
-
-	if (!eighty_ninty_three(drive))
-		mode = min(mode, (u8)1);
-	return mode;
-}
-
 /*
  * Configuration functions
  */
@@ -563,7 +553,7 @@ static int sis5513_tune_chipset (ide_dri
 	u8 drive_pci, reg, speed;
 	u32 regdw;
 
-	speed = ide_rate_filter(sis5513_ratemask(drive), xferspeed);
+	speed = ide_rate_filter(drive, xferspeed);
 
 	/* See config_art_rwp_pio for drive pci config registers */
 	drive_pci = 0x40;
@@ -653,7 +643,7 @@ static void sis5513_tune_drive (ide_driv
  */
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
-	u8 speed	= ide_dma_speed(drive, sis5513_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 #ifdef DEBUG
 	printk("SIS5513: config_chipset_for_dma, drive %d, ultra %x\n",
Index: b/drivers/ide/pci/slc90e66.c
===================================================================
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -21,15 +21,6 @@
 
 #include <asm/io.h>
 
-static u8 slc90e66_ratemask (ide_drive_t *drive)
-{
-	u8 mode	= 2;
-
-	if (!eighty_ninty_three(drive))
-		mode = min_t(u8, mode, 1);
-	return mode;
-}
-
 static u8 slc90e66_dma_2_pio (u8 xfer_rate) {
 	switch(xfer_rate) {
 		case XFER_UDMA_4:
@@ -119,7 +110,7 @@ static int slc90e66_tune_chipset (ide_dr
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= hwif->pci_dev;
 	u8 maslave		= hwif->channel ? 0x42 : 0x40;
-	u8 speed	= ide_rate_filter(slc90e66_ratemask(drive), xferspeed);
+	u8 speed		= ide_rate_filter(drive, xferspeed);
 	int sitre = 0, a_speed	= 7 << (drive->dn * 4);
 	int u_speed = 0, u_flag = 1 << drive->dn;
 	u16			reg4042, reg44, reg48, reg4a;
@@ -168,7 +159,7 @@ static int slc90e66_tune_chipset (ide_dr
 
 static int slc90e66_config_drive_for_dma (ide_drive_t *drive)
 {
-	u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!speed)
 		return 0;
Index: b/drivers/ide/pci/tc86c001.c
===================================================================
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -13,18 +13,13 @@
 #include <linux/pci.h>
 #include <linux/ide.h>
 
-static inline u8 tc86c001_ratemask(ide_drive_t *drive)
-{
-	return eighty_ninty_three(drive) ? 2 : 1;
-}
-
 static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	unsigned long scr_port	= hwif->config_data + (drive->dn ? 0x02 : 0x00);
 	u16 mode, scr		= hwif->INW(scr_port);
 
-	speed = ide_rate_filter(tc86c001_ratemask(drive), speed);
+	speed = ide_rate_filter(drive, speed);
 
 	switch (speed) {
 		case XFER_UDMA_4:	mode = 0x00c0; break;
@@ -174,7 +169,7 @@ static int tc86c001_busproc(ide_drive_t 
 
 static int config_chipset_for_dma(ide_drive_t *drive)
 {
-	u8 speed = ide_dma_speed(drive, tc86c001_ratemask(drive));
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!speed)
 		return 0;
Index: b/drivers/ide/pci/triflex.c
===================================================================
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -48,7 +48,7 @@ static int triflex_tune_chipset(ide_driv
 	u16 timing = 0;
 	u32 triflex_timings = 0;
 	u8 unit = (drive->select.b.unit & 0x01);
-	u8 speed = ide_rate_filter(0, xferspeed);
+	u8 speed = ide_rate_filter(drive, xferspeed);
 	
 	pci_read_config_dword(dev, channel_offset, &triflex_timings);
 	
@@ -102,7 +102,7 @@ static void triflex_tune_drive(ide_drive
 
 static int triflex_config_drive_for_dma(ide_drive_t *drive)
 {
-	int speed = ide_dma_speed(drive, 0); /* No ultra speeds */
+	u8 speed = ide_max_dma_mode(drive);
 
 	if (!speed)
 		return 0;
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -717,11 +717,8 @@ typedef struct hwif_s {
 	int	(*quirkproc)(ide_drive_t *);
 	/* driver soft-power interface */
 	int	(*busproc)(ide_drive_t *, int);
-//	/* host rate limiter */
-//	u8	(*ratemask)(ide_drive_t *);
-//	/* device rate limiter */
-//	u8	(*ratefilter)(ide_drive_t *, u8);
 #endif
+	u8 (*filter_udma_mask)(ide_drive_t *);
 
 	void (*ata_input_data)(ide_drive_t *, void *, u32);
 	void (*ata_output_data)(ide_drive_t *, void *, u32);
@@ -1277,6 +1274,7 @@ int ide_in_drive_list(struct hd_driveid 
 int __ide_dma_bad_drive(ide_drive_t *);
 int __ide_dma_good_drive(ide_drive_t *);
 int ide_use_dma(ide_drive_t *);
+u8 ide_max_dma_mode(ide_drive_t *);
 void ide_dma_off(ide_drive_t *);
 void ide_dma_verbose(ide_drive_t *);
 int ide_set_dma(ide_drive_t *);
@@ -1303,6 +1301,7 @@ extern int __ide_dma_timeout(ide_drive_t
 
 #else
 static inline int ide_use_dma(ide_drive_t *drive) { return 0; }
+static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
 static inline void ide_dma_off(ide_drive_t *drive) { ; }
 static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
 static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
@@ -1347,8 +1346,7 @@ static inline void ide_set_hwifdata (ide
 }
 
 /* ide-lib.c */
-extern u8 ide_dma_speed(ide_drive_t *drive, u8 mode);
-extern u8 ide_rate_filter(u8 mode, u8 speed); 
+u8 ide_rate_filter(ide_drive_t *, u8);
 extern int ide_dma_enable(ide_drive_t *drive);
 extern char *ide_xfer_verbose(u8 xfer_rate);
 extern void ide_toggle_bounce(ide_drive_t *drive, int on);

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

* [PATCH 15/15] ide: add ide_tune_dma() helper
  2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
                   ` (13 preceding siblings ...)
  2007-01-19  0:32 ` [PATCH 14/15] ide: rework the code for selecting the best DMA transfer mode Bartlomiej Zolnierkiewicz
@ 2007-01-19  0:32 ` Bartlomiej Zolnierkiewicz
  14 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19  0:32 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

[PATCH] ide: add ide_tune_dma() helper

After reworking the code responsible for selecting the best DMA
transfer mode it is now possible to add generic ide_tune_dma() helper.

Convert some IDE PCI host drivers to use it (the ones left need more work).

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

---
 drivers/ide/ide-dma.c      |   20 ++++++++++++++++++++
 drivers/ide/pci/aec62xx.c  |   13 +------------
 drivers/ide/pci/atiixp.c   |   22 +---------------------
 drivers/ide/pci/cs5535.c   |   15 +--------------
 drivers/ide/pci/hpt34x.c   |   20 +-------------------
 drivers/ide/pci/hpt366.c   |   20 +-------------------
 drivers/ide/pci/it8213.c   |   21 +--------------------
 drivers/ide/pci/jmicron.c  |   21 +--------------------
 drivers/ide/pci/piix.c     |   26 +-------------------------
 drivers/ide/pci/sis5513.c  |   21 +--------------------
 drivers/ide/pci/slc90e66.c |   13 +------------
 drivers/ide/pci/tc86c001.c |   13 +------------
 drivers/ide/pci/triflex.c  |   13 +------------
 include/linux/ide.h        |    2 ++
 14 files changed, 34 insertions(+), 206 deletions(-)

Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -779,6 +779,26 @@ u8 ide_max_dma_mode(ide_drive_t *drive)
 
 EXPORT_SYMBOL_GPL(ide_max_dma_mode);
 
+int ide_tune_dma(ide_drive_t *drive)
+{
+	u8 speed;
+
+	/* TODO: use only ide_max_dma_mode() */
+	if (!ide_use_dma(drive))
+		return 0;
+
+	speed = ide_max_dma_mode(drive);
+
+	if (!speed)
+		return 0;
+
+	drive->hwif->speedproc(drive, speed);
+
+	return ide_dma_enable(drive);
+}
+
+EXPORT_SYMBOL_GPL(ide_tune_dma);
+
 void ide_dma_verbose(ide_drive_t *drive)
 {
 	struct hd_driveid *id	= drive->id;
Index: b/drivers/ide/pci/aec62xx.c
===================================================================
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -154,17 +154,6 @@ static int aec62xx_tune_chipset (ide_dri
 	}
 }
 
-static int config_chipset_for_dma (ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-	if (!(speed))
-		return 0;
-
-	(void) aec62xx_tune_chipset(drive, speed);
-	return ide_dma_enable(drive);
-}
-
 static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio)
 {
 	u8 speed = 0;
@@ -183,7 +172,7 @@ static void aec62xx_tune_drive (ide_driv
 
 static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+	if (ide_tune_dma(drive))
 		return 0;
 
 	if (ide_use_fast_pio(drive))
Index: b/drivers/ide/pci/atiixp.c
===================================================================
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -207,26 +207,6 @@ static int atiixp_speedproc(ide_drive_t 
 }
 
 /**
- *	atiixp_config_drive_for_dma	-	configure drive for DMA
- *	@drive: IDE drive to configure
- *
- *	Set up a ATIIXP interface channel for the best available speed.
- *	We prefer UDMA if it is available and then MWDMA. If DMA is
- *	not available we switch to PIO and return 0.
- */
-
-static int atiixp_config_drive_for_dma(ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-	if (!speed)
-		return 0;
-
-	(void) atiixp_speedproc(drive, speed);
-	return ide_dma_enable(drive);
-}
-
-/**
  *	atiixp_dma_check	-	set up an IDE device
  *	@drive: IDE drive to configure
  *
@@ -240,7 +220,7 @@ static int atiixp_dma_check(ide_drive_t 
 
 	drive->init_speed = 0;
 
-	if (ide_use_dma(drive) && atiixp_config_drive_for_dma(drive))
+	if (ide_tune_dma(drive))
 		return 0;
 
 	if (ide_use_fast_pio(drive)) {
Index: b/drivers/ide/pci/cs5535.c
===================================================================
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -164,26 +164,13 @@ static void cs5535_tuneproc(ide_drive_t 
 	cs5535_set_speed(drive, xferspeed);
 }
 
-static int cs5535_config_drive_for_dma(ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-	/* If no DMA speed was available then let dma_check hit pio */
-	if (!speed) {
-		return 0;
-	}
-
-	cs5535_set_drive(drive, speed);
-	return ide_dma_enable(drive);
-}
-
 static int cs5535_dma_check(ide_drive_t *drive)
 {
 	u8 speed;
 
 	drive->init_speed = 0;
 
-	if (ide_use_dma(drive) && cs5535_config_drive_for_dma(drive))
+	if (ide_tune_dma(drive))
 		return 0;
 
 	if (ide_use_fast_pio(drive)) {
Index: b/drivers/ide/pci/hpt34x.c
===================================================================
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -84,29 +84,11 @@ static void hpt34x_tune_drive (ide_drive
 	(void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio));
 }
 
-/*
- * 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.  Initially for designed for
- * HPT343 UDMA chipset by HighPoint|Triones Technologies, Inc.
- */
-
-static int config_chipset_for_dma (ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-	if (!(speed))
-		return 0;
-
-	(void) hpt34x_tune_chipset(drive, speed);
-	return ide_dma_enable(drive);
-}
-
 static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
 {
 	drive->init_speed = 0;
 
-	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+	if (ide_tune_dma(drive))
 #ifndef CONFIG_HPT34X_AUTODMA
 		return -1;
 #else
Index: b/drivers/ide/pci/hpt366.c
===================================================================
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -668,24 +668,6 @@ static void hpt3xx_tune_drive(ide_drive_
 	(void) hpt3xx_tune_chipset (drive, XFER_PIO_0 + pio);
 }
 
-/*
- * 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.  Initially designed for
- * HPT366 UDMA chipset by HighPoint|Triones Technologies, Inc.
- *
- */
-static int config_chipset_for_dma(ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-	if (!speed)
-		return 0;
-
-	(void) hpt3xx_tune_chipset(drive, speed);
-	return ide_dma_enable(drive);
-}
-
 static int hpt3xx_quirkproc(ide_drive_t *drive)
 {
 	struct hd_driveid *id	= drive->id;
@@ -740,7 +722,7 @@ static int hpt366_config_drive_xfer_rate
 {
 	drive->init_speed = 0;
 
-	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+	if (ide_tune_dma(drive))
 		return 0;
 
 	if (ide_use_fast_pio(drive))
Index: b/drivers/ide/pci/it8213.c
===================================================================
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -197,25 +197,6 @@ static int it8213_tune_chipset (ide_driv
 	return ide_config_drive_speed(drive, speed);
 }
 
-/*
- *	config_chipset_for_dma	-	configure for DMA
- *	@drive: drive to configure
- *
- *	Called by the IDE layer when it wants the timings set up.
- */
-
-static int config_chipset_for_dma (ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-	if (!speed)
-		return 0;
-
-	it8213_tune_chipset(drive, speed);
-
-	return ide_dma_enable(drive);
-}
-
 /**
  *	it8213_configure_drive_for_dma	-	set up for DMA transfers
  *	@drive: drive we are going to set up
@@ -230,7 +211,7 @@ static int it8213_config_drive_for_dma (
 {
 	u8 pio;
 
-	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+	if (ide_tune_dma(drive))
 		return 0;
 
 	pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
Index: b/drivers/ide/pci/jmicron.c
===================================================================
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -119,25 +119,6 @@ static int jmicron_tune_chipset (ide_dri
 }
 
 /**
- *	config_chipset_for_dma	-	configure for DMA
- *	@drive: drive to configure
- *
- *	As the JMicron snoops for timings all we actually need to do is
- *	make sure we don't set an invalid mode.
- */
-
-static int config_chipset_for_dma (ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-	if (!speed)
-		return 0;
-
-	jmicron_tune_chipset(drive, speed);
-	return ide_dma_enable(drive);
-}
-
-/**
  *	jmicron_configure_drive_for_dma	-	set up for DMA transfers
  *	@drive: drive we are going to set up
  *
@@ -147,7 +128,7 @@ static int config_chipset_for_dma (ide_d
 
 static int jmicron_config_drive_for_dma (ide_drive_t *drive)
 {
-	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+	if (ide_tune_dma(drive))
 		return 0;
 
 	config_jmicron_chipset_for_pio(drive, 1);
Index: b/drivers/ide/pci/piix.c
===================================================================
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -291,30 +291,6 @@ static int piix_tune_chipset (ide_drive_
 }
 
 /**
- *	piix_config_drive_for_dma	-	configure drive for DMA
- *	@drive: IDE drive to configure
- *
- *	Set up a PIIX interface channel for the best available speed.
- *	We prefer UDMA if it is available and then MWDMA.  If DMA is
- *	not available we switch to PIO and return 0.
- */
- 
-static int piix_config_drive_for_dma (ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-	/*
-	 * If no DMA speed was available or the chipset has DMA bugs
-	 * then disable DMA and use PIO
-	 */
-	if (!speed)
-		return 0;
-
-	(void) piix_tune_chipset(drive, speed);
-	return ide_dma_enable(drive);
-}
-
-/**
  *	piix_config_drive_xfer_rate	-	set up an IDE device
  *	@drive: IDE drive to configure
  *
@@ -326,7 +302,7 @@ static int piix_config_drive_xfer_rate (
 {
 	drive->init_speed = 0;
 
-	if (ide_use_dma(drive) && piix_config_drive_for_dma(drive))
+	if (ide_tune_dma(drive))
 		return 0;
 
 	if (ide_use_fast_pio(drive)) {
Index: b/drivers/ide/pci/sis5513.c
===================================================================
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -638,32 +638,13 @@ static void sis5513_tune_drive (ide_driv
 	(void) config_chipset_for_pio(drive, pio);
 }
 
-/*
- * ((id->hw_config & 0x4000|0x2000) && (HWIF(drive)->udma_four))
- */
-static int config_chipset_for_dma (ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-#ifdef DEBUG
-	printk("SIS5513: config_chipset_for_dma, drive %d, ultra %x\n",
-	       drive->dn, drive->id->dma_ultra);
-#endif
-
-	if (!(speed))
-		return 0;
-
-	sis5513_tune_chipset(drive, speed);
-	return ide_dma_enable(drive);
-}
-
 static int sis5513_config_xfer_rate(ide_drive_t *drive)
 {
 	config_art_rwp_pio(drive, 5);
 
 	drive->init_speed = 0;
 
-	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+	if (ide_tune_dma(drive))
 		return 0;
 
 	if (ide_use_fast_pio(drive))
Index: b/drivers/ide/pci/slc90e66.c
===================================================================
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -157,22 +157,11 @@ static int slc90e66_tune_chipset (ide_dr
 	return (ide_config_drive_speed(drive, speed));
 }
 
-static int slc90e66_config_drive_for_dma (ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-	if (!speed)
-		return 0;
-
-	(void) slc90e66_tune_chipset(drive, speed);
-	return ide_dma_enable(drive);
-}
-
 static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
 {
 	drive->init_speed = 0;
 
-	if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
+	if (ide_tune_dma(drive))
 		return 0;
 
 	if (ide_use_fast_pio(drive)) {
Index: b/drivers/ide/pci/tc86c001.c
===================================================================
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -167,20 +167,9 @@ static int tc86c001_busproc(ide_drive_t 
 	return 0;
 }
 
-static int config_chipset_for_dma(ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-	if (!speed)
-		return 0;
-
-	(void) tc86c001_tune_chipset(drive, speed);
-	return ide_dma_enable(drive);
-}
-
 static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+	if (ide_tune_dma(drive))
 		return 0;
 
 	if (ide_use_fast_pio(drive))
Index: b/drivers/ide/pci/triflex.c
===================================================================
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -100,20 +100,9 @@ static void triflex_tune_drive(ide_drive
 	(void) triflex_tune_chipset(drive, (XFER_PIO_0 + use_pio));
 }
 
-static int triflex_config_drive_for_dma(ide_drive_t *drive)
-{
-	u8 speed = ide_max_dma_mode(drive);
-
-	if (!speed)
-		return 0;
-
-	(void) triflex_tune_chipset(drive, speed);
-	 return ide_dma_enable(drive);
-}
-
 static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	if (ide_use_dma(drive) && triflex_config_drive_for_dma(drive))
+	if (ide_tune_dma(drive))
 		return 0;
 
 	triflex_tune_drive(drive, 255);
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1275,6 +1275,7 @@ int __ide_dma_bad_drive(ide_drive_t *);
 int __ide_dma_good_drive(ide_drive_t *);
 int ide_use_dma(ide_drive_t *);
 u8 ide_max_dma_mode(ide_drive_t *);
+int ide_tune_dma(ide_drive_t *);
 void ide_dma_off(ide_drive_t *);
 void ide_dma_verbose(ide_drive_t *);
 int ide_set_dma(ide_drive_t *);
@@ -1302,6 +1303,7 @@ extern int __ide_dma_timeout(ide_drive_t
 #else
 static inline int ide_use_dma(ide_drive_t *drive) { return 0; }
 static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
+static inline int ide_tune_dma(ide_drive_t *drive) { return 0; }
 static inline void ide_dma_off(ide_drive_t *drive) { ; }
 static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
 static inline int ide_set_dma(ide_drive_t *drive) { return 1; }

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

* Re: [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case
  2007-01-19  0:31 ` [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case Bartlomiej Zolnierkiewicz
@ 2007-01-19 16:26   ` Sergei Shtylyov
       [not found]     ` <58cb370e0701191047h524434eobdb9d86ed614bc71@mail.gmail.com>
  0 siblings, 1 reply; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-19 16:26 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:
> [PATCH] ide: disable DMA in ->ide_dma_check for "no IORDY" case

    I've looked thru the code, and found more issues with the PIO fallback 
there. Will try to cook up patches for at least some drivers...

> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

> Index: b/drivers/ide/pci/aec62xx.c
> ===================================================================
> --- a/drivers/ide/pci/aec62xx.c
> +++ b/drivers/ide/pci/aec62xx.c
> @@ -214,12 +214,10 @@ static int aec62xx_config_drive_xfer_rat
>  	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>  		return hwif->ide_dma_on(drive);
>  
> -	if (ide_use_fast_pio(drive)) {
> +	if (ide_use_fast_pio(drive))
>  		aec62xx_tune_drive(drive, 5);

    This function looks like it's working (thouugh having the wrong limit of 
PIO5 on auto-tuning) but is unnecassary complex.
    Heh, the driver is certainly a rip-off form hpt366.c. What a doubtful 
example they have chosen... :-)

> Index: b/drivers/ide/pci/atiixp.c
> ===================================================================
> --- a/drivers/ide/pci/atiixp.c
> +++ b/drivers/ide/pci/atiixp.c
> @@ -264,10 +264,9 @@ static int atiixp_dma_check(ide_drive_t 
>  		tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
>  		speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;

    It's simply stupid to convert PIO mode to PIO mode. The whole idea is 
doubtful as well..

>  		hwif->speedproc(drive, speed);

    Well, well, the tuneproc() method can't ahndle auto-tunuing here (255)...
And it also doesn't set up drive's own speed. The code seem to be another 
rip-off from piix.c, repeating all its mistakes... :-)

> Index: b/drivers/ide/pci/cmd64x.c
> ===================================================================
> --- a/drivers/ide/pci/cmd64x.c
> +++ b/drivers/ide/pci/cmd64x.c
> @@ -479,12 +479,10 @@ static int cmd64x_config_drive_for_dma (
>  	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>  		return hwif->ide_dma_on(drive);
>  
> -	if (ide_use_fast_pio(drive)) {
> +	if (ide_use_fast_pio(drive))
>  		config_chipset_for_pio(drive, 1);

    This function will always set PIO mode 4. Mess.

> Index: b/drivers/ide/pci/cs5535.c
> ===================================================================
> --- a/drivers/ide/pci/cs5535.c
> +++ b/drivers/ide/pci/cs5535.c
> @@ -206,10 +206,9 @@ static int cs5535_dma_check(ide_drive_t 
>  	if (ide_use_fast_pio(drive)) {
>  		speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
>  		cs5535_set_drive(drive, speed);

    Could be folded into tuneproc() method call.

> Index: b/drivers/ide/pci/pdc202xx_old.c
> ===================================================================
> --- a/drivers/ide/pci/pdc202xx_old.c
> +++ b/drivers/ide/pci/pdc202xx_old.c
> @@ -339,12 +339,10 @@ static int pdc202xx_config_drive_xfer_ra
>  	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>  		return hwif->ide_dma_on(drive);
>  
> -	if (ide_use_fast_pio(drive)) {
> +	if (ide_use_fast_pio(drive))
>  		hwif->tuneproc(drive, 5);

    This driver's tuneproc() method always auto-tunes here instead of setting 
what it's told too -- I'll send a patch...

> Index: b/drivers/ide/pci/siimage.c
> ===================================================================
> --- a/drivers/ide/pci/siimage.c
> +++ b/drivers/ide/pci/siimage.c
> @@ -420,12 +420,10 @@ static int siimage_config_drive_for_dma 
>  	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>  		return hwif->ide_dma_on(drive);
>  
> -	if (ide_use_fast_pio(drive)) {
> +	if (ide_use_fast_pio(drive))
>  		config_chipset_for_pio(drive, 1);

    This function will also always set PIO mode 4. More mess.

> Index: b/drivers/ide/pci/sis5513.c
> ===================================================================
> --- a/drivers/ide/pci/sis5513.c
> +++ b/drivers/ide/pci/sis5513.c
> @@ -678,12 +678,10 @@ static int sis5513_config_xfer_rate(ide_
>  	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>  		return hwif->ide_dma_on(drive);
>  
> -	if (ide_use_fast_pio(drive)) {
> +	if (ide_use_fast_pio(drive))
>  		sis5513_tune_drive(drive, 5);

     Ugh, PIO fallback effectively always tries to set mode 4 here (thanks 
it's not 5). Mess.

MBR, Sergei

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

* Re: [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case
       [not found]     ` <58cb370e0701191047h524434eobdb9d86ed614bc71@mail.gmail.com>
@ 2007-01-19 19:11       ` Bartlomiej Zolnierkiewicz
  2007-01-19 19:35         ` Sergei Shtylyov
  0 siblings, 1 reply; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19 19:11 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-ide, linux-kernel


Sergei Shtylyov wrote:
> Hello.

Hi,

> Bartlomiej Zolnierkiewicz wrote:
>> [PATCH] ide: disable DMA in ->ide_dma_check for "no IORDY" case
> 
>    I've looked thru the code, and found more issues with the PIO fallback
> there. Will try to cook up patches for at least some drivers...

Great, if possible please base them on top of the IDE tree...

>> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
> 
>> Index: b/drivers/ide/pci/aec62xx.c
>> ===================================================================
>> --- a/drivers/ide/pci/aec62xx.c
>> +++ b/drivers/ide/pci/aec62xx.c
>> @@ -214,12 +214,10 @@ static int aec62xx_config_drive_xfer_rat
>>       if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>               return hwif->ide_dma_on(drive);
>>
>> -     if (ide_use_fast_pio(drive)) {
>> +     if (ide_use_fast_pio(drive))
>>               aec62xx_tune_drive(drive, 5);
> 
>    This function looks like it's working (thouugh having the wrong limit of
> PIO5 on auto-tuning) but is unnecassary complex.

Yes, it seems that there are actually two bugs here:
* the maximum allowed PIO mode should be PIO4 not PIO5
* for auto-tuning ("pio" == 255) it incorrectly sets PIO0
  (255 fails to the default case in the switch statement)

>    Heh, the driver is certainly a rip-off form hpt366.c. What a doubtful
> example they have chosen... :-)

hehe

>> Index: b/drivers/ide/pci/atiixp.c
>> ===================================================================
>> --- a/drivers/ide/pci/atiixp.c
>> +++ b/drivers/ide/pci/atiixp.c
>> @@ -264,10 +264,9 @@ static int atiixp_dma_check(ide_drive_t
>>               tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
>>               speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
> 
>    It's simply stupid to convert PIO mode to PIO mode. The whole idea is
> doubtful as well..

It is side-effect of basing atiixp on piix driver.  Fixing it will allow PIO1
to be used (good) because atiixp_dma_2_pio() always downgrades PIO1 to PIO0
(leftover from piix - on Intel chipsets same timings are used for PIO0/1).

>>               hwif->speedproc(drive, speed);
> 
>    Well, well, the tuneproc() method can't ahndle auto-tunuing here
> (255)...

Yes, definitely a bug.

> And it also doesn't set up drive's own speed. The code seem to be another
> rip-off from piix.c, repeating all its mistakes... :-)

:)

>> Index: b/drivers/ide/pci/cmd64x.c
>> ===================================================================
>> --- a/drivers/ide/pci/cmd64x.c
>> +++ b/drivers/ide/pci/cmd64x.c
>> @@ -479,12 +479,10 @@ static int cmd64x_config_drive_for_dma (
>>       if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>               return hwif->ide_dma_on(drive);
>>
>> -     if (ide_use_fast_pio(drive)) {
>> +     if (ide_use_fast_pio(drive))
>>               config_chipset_for_pio(drive, 1);
> 
>    This function will always set PIO mode 4. Mess.

Yep.

>> Index: b/drivers/ide/pci/cs5535.c
>> ===================================================================
>> --- a/drivers/ide/pci/cs5535.c
>> +++ b/drivers/ide/pci/cs5535.c
>> @@ -206,10 +206,9 @@ static int cs5535_dma_check(ide_drive_t
>>       if (ide_use_fast_pio(drive)) {
>>               speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
>>               cs5535_set_drive(drive, speed);
> 
>    Could be folded into tuneproc() method call.

Using ->tuneproc() will also set the PIO mode on the drive
which is not done currently... 

>> Index: b/drivers/ide/pci/pdc202xx_old.c
>> ===================================================================
>> --- a/drivers/ide/pci/pdc202xx_old.c
>> +++ b/drivers/ide/pci/pdc202xx_old.c
>> @@ -339,12 +339,10 @@ static int pdc202xx_config_drive_xfer_ra
>>       if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>               return hwif->ide_dma_on(drive);
>>
>> -     if (ide_use_fast_pio(drive)) {
>> +     if (ide_use_fast_pio(drive))
>>               hwif->tuneproc(drive, 5);
> 
>    This driver's tuneproc() method always auto-tunes here instead of
> setting
> what it's told too -- I'll send a patch...

Please do...

>> Index: b/drivers/ide/pci/siimage.c
>> ===================================================================
>> --- a/drivers/ide/pci/siimage.c
>> +++ b/drivers/ide/pci/siimage.c
>> @@ -420,12 +420,10 @@ static int siimage_config_drive_for_dma
>>       if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>               return hwif->ide_dma_on(drive);
>>
>> -     if (ide_use_fast_pio(drive)) {
>> +     if (ide_use_fast_pio(drive))
>>               config_chipset_for_pio(drive, 1);
> 
>    This function will also always set PIO mode 4. More mess.

Yep, same bug as in cmd64x.c.

>> Index: b/drivers/ide/pci/sis5513.c
>> ===================================================================
>> --- a/drivers/ide/pci/sis5513.c
>> +++ b/drivers/ide/pci/sis5513.c
>> @@ -678,12 +678,10 @@ static int sis5513_config_xfer_rate(ide_
>>       if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>               return hwif->ide_dma_on(drive);
>>
>> -     if (ide_use_fast_pio(drive)) {
>> +     if (ide_use_fast_pio(drive))
>>               sis5513_tune_drive(drive, 5);
> 
>     Ugh, PIO fallback effectively always tries to set mode 4 here (thanks
> it's not 5). Mess.

Yep, but it seems to be even more complicated since config_art_rwp_pio()
is a mess^2 - chipset is programmed to the best PIO mode while the
device is set to PIO4... *sigh*...

Thanks,
Bart


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

* Re: [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case
  2007-01-19 19:11       ` Bartlomiej Zolnierkiewicz
@ 2007-01-19 19:35         ` Sergei Shtylyov
       [not found]           ` <58cb370e0701191200i10119313i4aacae9c504a02e4@mail.gmail.com>
  0 siblings, 1 reply; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-19 19:35 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:

>>>[PATCH] ide: disable DMA in ->ide_dma_check for "no IORDY" case

>>   I've looked thru the code, and found more issues with the PIO fallback
>>there. Will try to cook up patches for at least some drivers...

> Great, if possible please base them on top of the IDE tree...

    Erm, I had doubts about it (having in mind that all that code is more of a 
cleanups than fixes). Maybe it'd be a good idea to separate the fix and 
cleanup series somehow...

>>>Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

>>>Index: b/drivers/ide/pci/aec62xx.c
>>>===================================================================
>>>--- a/drivers/ide/pci/aec62xx.c
>>>+++ b/drivers/ide/pci/aec62xx.c
>>>@@ -214,12 +214,10 @@ static int aec62xx_config_drive_xfer_rat
>>>      if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>>              return hwif->ide_dma_on(drive);
>>>
>>>-     if (ide_use_fast_pio(drive)) {
>>>+     if (ide_use_fast_pio(drive))
>>>              aec62xx_tune_drive(drive, 5);
>>
>>   This function looks like it's working (thouugh having the wrong limit of
>>PIO5 on auto-tuning) but is unnecassary complex.

> Yes, it seems that there are actually two bugs here:
> * the maximum allowed PIO mode should be PIO4 not PIO5
> * for auto-tuning ("pio" == 255) it incorrectly sets PIO0
>   (255 fails to the default case in the switch statement)

    Yeah, you if you pass 255, it won't work (so, drive->autotune must be 
broken). But the driver itself have the wrong idea of 5 meaning auto-tune, so 
fallback should still work.

>>   Heh, the driver is certainly a rip-off form hpt366.c. What a doubtful
>>example they have chosen... :-)

> hehe

    The driver's authorship explains it all. :-)

>>>Index: b/drivers/ide/pci/atiixp.c
>>>===================================================================
>>>--- a/drivers/ide/pci/atiixp.c
>>>+++ b/drivers/ide/pci/atiixp.c
>>>@@ -264,10 +264,9 @@ static int atiixp_dma_check(ide_drive_t
>>>              tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
>>>              speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;

>>   It's simply stupid to convert PIO mode to PIO mode. The whole idea is
>>doubtful as well..

> It is side-effect of basing atiixp on piix driver.  Fixing it will allow PIO1
> to be used (good) because atiixp_dma_2_pio() always downgrades PIO1 to PIO0
> (leftover from piix - on Intel chipsets same timings are used for PIO0/1).

>>>              hwif->speedproc(drive, speed);

>>   Well, well, the tuneproc() method can't ahndle auto-tunuing here
>>(255)...

> Yes, definitely a bug.

    Ugh... don't expect patches form me soon though. My first priority is the 
drivers that we support here...

>>And it also doesn't set up drive's own speed. The code seem to be another
>>rip-off from piix.c, repeating all its mistakes... :-)

> :)

>>>Index: b/drivers/ide/pci/cmd64x.c
>>>===================================================================
>>>--- a/drivers/ide/pci/cmd64x.c
>>>+++ b/drivers/ide/pci/cmd64x.c
>>>@@ -479,12 +479,10 @@ static int cmd64x_config_drive_for_dma (
>>>      if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>>              return hwif->ide_dma_on(drive);
>>>
>>>-     if (ide_use_fast_pio(drive)) {
>>>+     if (ide_use_fast_pio(drive))
>>>              config_chipset_for_pio(drive, 1);

>>   This function will always set PIO mode 4. Mess.

> Yep.

    I'm going to send the patch for both this and siimage.c...

>>>Index: b/drivers/ide/pci/cs5535.c
>>>===================================================================
>>>--- a/drivers/ide/pci/cs5535.c
>>>+++ b/drivers/ide/pci/cs5535.c
>>>@@ -206,10 +206,9 @@ static int cs5535_dma_check(ide_drive_t
>>>      if (ide_use_fast_pio(drive)) {
>>>              speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
>>>              cs5535_set_drive(drive, speed);

>>   Could be folded into tuneproc() method call.

> Using ->tuneproc() will also set the PIO mode on the drive
> which is not done currently... 

    Hm, ide_config_drive_speed() is called by both tuneproc() method and 
cs5535_set_drive(), so I saw no issue there...

>>>Index: b/drivers/ide/pci/sis5513.c
>>>===================================================================
>>>--- a/drivers/ide/pci/sis5513.c
>>>+++ b/drivers/ide/pci/sis5513.c
>>>@@ -678,12 +678,10 @@ static int sis5513_config_xfer_rate(ide_
>>>      if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>>              return hwif->ide_dma_on(drive);

>>>-     if (ide_use_fast_pio(drive)) {
>>>+     if (ide_use_fast_pio(drive))
>>>              sis5513_tune_drive(drive, 5);

>>    Ugh, PIO fallback effectively always tries to set mode 4 here (thanks
>>it's not 5). Mess.

> Yep, but it seems to be even more complicated since config_art_rwp_pio()
> is a mess^2 - chipset is programmed to the best PIO mode while the
> device is set to PIO4... *sigh*...

    Sorry, this one is low prio for me... :-)

> Thanks,
> Bart

MBR, Sergei

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

* Re: [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case
       [not found]           ` <58cb370e0701191200i10119313i4aacae9c504a02e4@mail.gmail.com>
@ 2007-01-19 21:43             ` Bartlomiej Zolnierkiewicz
  2007-01-20 17:09               ` Sergei Shtylyov
  0 siblings, 1 reply; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-19 21:43 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-ide, linux-kernel


Sergei Shtylyov wrote:
> Hello.
> 
> Bartlomiej Zolnierkiewicz wrote:
> 
>>>> [PATCH] ide: disable DMA in ->ide_dma_check for "no IORDY" case
> 
>>>   I've looked thru the code, and found more issues with the PIO fallback
>>> there. Will try to cook up patches for at least some drivers...
> 
>> Great, if possible please base them on top of the IDE tree...
> 
>    Erm, I had doubts about it (having in mind that all that code is more of a
> cleanups than fixes). Maybe it'd be a good idea to separate the fix and
> cleanup series somehow...

I generally tend do cleanups as a groundwork for the real fixes and separate
cleanups and fixes to have good base for dealing with regressions.  Often all
changes (cleanups/fixes) could be included in one patch but then I would have
had harsh times when debugging the regressions.  It matters a lot if you hit
an unknown (or known but the documentation is covered by NDA) hardware bug
- you can concentrate on a small patch changing the way in which hardware is
accessed instead of that big patch moving code around etc.

Also the thing is that the same bugs are propagated over many drivers so doing
cleanups which merge code before fixing the bug makes sense.  We can then fix
the damn bug once and for all and not worry about somebody copy-n-pasting
the bug from the yet-to-be-fixed driver (i.e. in the next patch IDE update
there will be patch to check return value of ->speedproc in ide_tune_dma(),
without ide-fix-dma-mask/ide-max-dma-mode/ide-tune-dma-helper patches
I would have to go over all drivers to fix this bug and still there won't
be a guarantee that same bug wouldn't be introduced in some new driver).

The other advantage of doing cleanups is that code becomes cleaner/simpler
which matters a lot for this codebase, i.e. ide-dma-off-void.patch exposed
(yet to be fixed) bug in set_using_dma() (->ide_dma_off_quietly always returns
0 which is passed by ->ide_dma_check to set_using_dma() which incorrectly
then calls ->ide_dma_on).

Moreover I don't find the current tree to be more of cleanups than fixes,
here is the analysis of current series file:

#
# -pata extraversion
#
pata-extraversion.patch
	-- n/a
#
# IDE patches from 2.6.20-rc3-mm1
#
toshiba-tc86c001-ide-driver-take-2.patch
toshiba-tc86c001-ide-driver-take-2-fix.patch
toshiba-tc86c001-ide-driver-take-2-fix-2.patch
	-- new driver
hpt3xx-rework-rate-filtering.patch
hpt3xx-rework-rate-filtering-tidy.patch
hpt3xx-print-the-real-chip-name-at-startup.patch
hpt3xx-switch-to-using-pci_get_slot.patch
hpt3xx-cache-channels-mcr-address.patch
hpt3x7-merge-speedproc-handlers.patch
hpt370-clean-up-dma-timeout-handling.patch
hpt3xx-init-code-rewrite.patch
piix-fix-82371mx-enablebits.patch
piix-tuneproc-fixes-cleanups.patch
slc90e66-carry-over-fixes-from-piix-driver.patch
hpt36x-pci-clock-detection-fix.patch
jmicron-warning-fix.patch
	-- fixes (but most have cleanups mixed in)
pdc202xx_new-remove-useless-code.patch
pdc202xx_-remove-check_in_drive_lists-abomination.patch
	-- cleanups
#
# IDE patches applied by Andrew (2.6.20-rc4-mm1)
#
atiixpc-remove-unused-code.patch
	-- cleanup
atiixpc-sb600-ide-only-has-one-channel.patch
atiixpc-add-cable-detection-support-for-ati-ide.patch
ide-generic-jmicron-has-its-own-drivers-now.patch
	-- fixes
ide-maintainers-entry.patch
	-- n/a
#
# IT8213
#
it8213-ide-driver.patch
it8213-ide-driver-update.patch
	-- new driver
#
# patches posted on Jan 11 2007
#
ia64-pci_get_legacy_ide_irq.patch
ide-pci-init-tags.patch
	-- fixes
pdc202xx_old-dead-code.patch
au1xxx-dead-code.patch
ide-pio-blacklisted.patch
ide-no-dsc-flag.patch
trm290-dma-ifdefs.patch
ide-pci-device-tables.patch
ide-dev-openers.patch
hpt366-init-dma.patch
cs5530-cleanup.patch
svwks-cleanup.patch
sis5513-config-xfer-rate.patch
ide-set-xfer-rate.patch
ide-use-fast-pio-v2.patch
ide-io-cleanup.patch
	-- cleanups
#
# Delkin CardBus CF driver (Mark Lord <mlord@pobox.com>)
#
delkin_cb-ide-driver.patch
	-- new driver
#
# IDE ACPI support (Hannes Reinecke <hare@suse.de>)
#
ide-acpi-support.patch
	-- new functionality (fixes PM on some machines)
#
# ide-pnp exit fix (Tejun Heo <htejun@gmail.com>)
#
ide-pnp-exit-fix.patch
	-- fix
#
# VIA IDE update (Josepch Chan <josephchan@via.com.tw>)
#
via-ide-update.patch
	-- fix
#
# patches posted on 18 Jan 2007
#
it8213-ide-driver-update-fixes.patch
	-- fix
ide-mmio-flag.patch
	-- cleanup
hpt34x-tune-chipset-fix.patch
	-- fix
ide-fix-pio-fallback.patch
	-- fix
piix-cleanup.patch
	-- cleanup
ide-dma-check-disable-dma-fix.patch
sgiioc4-ide-dma-check-fix.patch
	-- fixes
ide-set-dma-helper.patch
ide-dma-off-void.patch
ide-dma-host-on-void.patch
ide-fix-dma-masks.patch
ide-max-dma-mode.patch
ide-tune-dma-helper.patch
	-- cleanups

So it looks more like 50-50 with majority of fixes coming from you :)

However I understand that for some applications (stable distro etc) fixes
only tree would be more desired and if somebody would like to maintain
such tree I'm all for it. :)

OTOH getting patches against vanilla or -mm is perfectly fine with me
and if you would like me to shuffle ordering of the patches (but without
need of rewritting them) it also OK

>>>> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
> 
>>>> Index: b/drivers/ide/pci/aec62xx.c
>>>> ===================================================================
>>>> --- a/drivers/ide/pci/aec62xx.c
>>>> +++ b/drivers/ide/pci/aec62xx.c
>>>> @@ -214,12 +214,10 @@ static int aec62xx_config_drive_xfer_rat
>>>>      if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>>>              return hwif->ide_dma_on(drive);
>>>>
>>>> -     if (ide_use_fast_pio(drive)) {
>>>> +     if (ide_use_fast_pio(drive))
>>>>              aec62xx_tune_drive(drive, 5);
>>>
>>>   This function looks like it's working (thouugh having the wrong
>>> limit of
>>> PIO5 on auto-tuning) but is unnecassary complex.
> 
>> Yes, it seems that there are actually two bugs here:
>> * the maximum allowed PIO mode should be PIO4 not PIO5
>> * for auto-tuning ("pio" == 255) it incorrectly sets PIO0
>>   (255 fails to the default case in the switch statement)
> 
>    Yeah, you if you pass 255, it won't work (so, drive->autotune must be
> broken). But the driver itself have the wrong idea of 5 meaning auto-tune, so
> fallback should still work.

Yep.

>>>   Heh, the driver is certainly a rip-off form hpt366.c. What a doubtful
>>> example they have chosen... :-)
> 
>> hehe
> 
>    The driver's authorship explains it all. :-)
> 
>>>> Index: b/drivers/ide/pci/atiixp.c
>>>> ===================================================================
>>>> --- a/drivers/ide/pci/atiixp.c
>>>> +++ b/drivers/ide/pci/atiixp.c
>>>> @@ -264,10 +264,9 @@ static int atiixp_dma_check(ide_drive_t
>>>>              tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
>>>>              speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) +
>>>> XFER_PIO_0;
> 
>>>   It's simply stupid to convert PIO mode to PIO mode. The whole idea is
>>> doubtful as well..
> 
>> It is side-effect of basing atiixp on piix driver.  Fixing it will allow PIO1
>> to be used (good) because atiixp_dma_2_pio() always downgrades PIO1 to PIO0
>> (leftover from piix - on Intel chipsets same timings are used for PIO0/1).
> 
>>>>              hwif->speedproc(drive, speed);
> 
>>>   Well, well, the tuneproc() method can't ahndle auto-tunuing here
>>> (255)...
> 
>> Yes, definitely a bug.
> 
>    Ugh... don't expect patches form me soon though. My first priority is the
> drivers that we support here...

OK, added at the end of my TODO (just in case)

>>> And it also doesn't set up drive's own speed. The code seem to be another
>>> rip-off from piix.c, repeating all its mistakes... :-)
> 
>> :)
> 
>>>> Index: b/drivers/ide/pci/cmd64x.c
>>>> ===================================================================
>>>> --- a/drivers/ide/pci/cmd64x.c
>>>> +++ b/drivers/ide/pci/cmd64x.c
>>>> @@ -479,12 +479,10 @@ static int cmd64x_config_drive_for_dma (
>>>>      if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>>>              return hwif->ide_dma_on(drive);
>>>>
>>>> -     if (ide_use_fast_pio(drive)) {
>>>> +     if (ide_use_fast_pio(drive))
>>>>              config_chipset_for_pio(drive, 1);
> 
>>>   This function will always set PIO mode 4. Mess.
> 
>> Yep.
> 
>    I'm going to send the patch for both this and siimage.c...

OK

>>>> Index: b/drivers/ide/pci/cs5535.c
>>>> ===================================================================
>>>> --- a/drivers/ide/pci/cs5535.c
>>>> +++ b/drivers/ide/pci/cs5535.c
>>>> @@ -206,10 +206,9 @@ static int cs5535_dma_check(ide_drive_t
>>>>      if (ide_use_fast_pio(drive)) {
>>>>              speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
>>>>              cs5535_set_drive(drive, speed);
> 
>>>   Could be folded into tuneproc() method call.
> 
>> Using ->tuneproc() will also set the PIO mode on the drive
>> which is not done currently...
> 
>    Hm, ide_config_drive_speed() is called by both tuneproc() method and
> cs5535_set_drive(), so I saw no issue there...

indeed

>>>> Index: b/drivers/ide/pci/sis5513.c
>>>> ===================================================================
>>>> --- a/drivers/ide/pci/sis5513.c
>>>> +++ b/drivers/ide/pci/sis5513.c
>>>> @@ -678,12 +678,10 @@ static int sis5513_config_xfer_rate(ide_
>>>>      if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>>>              return hwif->ide_dma_on(drive);
> 
>>>> -     if (ide_use_fast_pio(drive)) {
>>>> +     if (ide_use_fast_pio(drive))
>>>>              sis5513_tune_drive(drive, 5);
> 
>>>    Ugh, PIO fallback effectively always tries to set mode 4 here (thanks
>>> it's not 5). Mess.
> 
>> Yep, but it seems to be even more complicated since config_art_rwp_pio()
>> is a mess^2 - chipset is programmed to the best PIO mode while the
>> device is set to PIO4... *sigh*...
> 
>    Sorry, this one is low prio for me... :-)

OK

Bart


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

* Re: [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case
  2007-01-19 21:43             ` Bartlomiej Zolnierkiewicz
@ 2007-01-20 17:09               ` Sergei Shtylyov
       [not found]                 ` <58cb370e0701200947p578f4d74g1fee511ded6c9a77@mail.gmail.com>
  0 siblings, 1 reply; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-20 17:09 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:

>>>>  I've looked thru the code, and found more issues with the PIO fallback
>>>>there. Will try to cook up patches for at least some drivers...

>>>Great, if possible please base them on top of the IDE tree...

>>   Erm, I had doubts about it (having in mind that all that code is more of a
>>cleanups than fixes). Maybe it'd be a good idea to separate the fix and
>>cleanup series somehow...

> I generally tend do cleanups as a groundwork for the real fixes and separate
> cleanups and fixes to have good base for dealing with regressions.  Often all
> changes (cleanups/fixes) could be included in one patch but then I would have
> had harsh times when debugging the regressions.  It matters a lot if you hit
> an unknown (or known but the documentation is covered by NDA) hardware bug
> - you can concentrate on a small patch changing the way in which hardware is
> accessed instead of that big patch moving code around etc.

> Also the thing is that the same bugs are propagated over many drivers so doing
> cleanups which merge code before fixing the bug makes sense.  We can then fix
> the damn bug once and for all and not worry about somebody copy-n-pasting
> the bug from the yet-to-be-fixed driver (i.e. in the next patch IDE update
> there will be patch to check return value of ->speedproc in ide_tune_dma(),
> without ide-fix-dma-mask/ide-max-dma-mode/ide-tune-dma-helper patches
> I would have to go over all drivers to fix this bug and still there won't
> be a guarantee that same bug wouldn't be introduced in some new driver).

> The other advantage of doing cleanups is that code becomes cleaner/simpler
> which matters a lot for this codebase, i.e. ide-dma-off-void.patch exposed
> (yet to be fixed) bug in set_using_dma() (->ide_dma_off_quietly always returns
> 0 which is passed by ->ide_dma_check to set_using_dma() which incorrectly
> then calls ->ide_dma_on).

    Well, this seems a newly intruduced bug.

    It's all fine but goes somewhat against Linus' policy as far as I 
understnad it: fixes are merged all the time while cleanups (along with new 
code) are merged mostly duting the merge window.

> Moreover I don't find the current tree to be more of cleanups than fixes,
> here is the analysis of current series file:

    Maybe I slightly exaggerated, being impressed by the volume of your recent
changes. :-)
    But still...

> #
> # IDE patches from 2.6.20-rc3-mm1
> #
> toshiba-tc86c001-ide-driver-take-2.patch
> toshiba-tc86c001-ide-driver-take-2-fix.patch
> toshiba-tc86c001-ide-driver-take-2-fix-2.patch
> 	-- new driver

     I'd count that as cleanup, since it's definitely not fix. ;-)

> hpt3xx-rework-rate-filtering.patch
> hpt3xx-rework-rate-filtering-tidy.patch
> hpt3xx-print-the-real-chip-name-at-startup.patch
> hpt3xx-switch-to-using-pci_get_slot.patch
> hpt3xx-cache-channels-mcr-address.patch
> hpt3x7-merge-speedproc-handlers.patch
> hpt370-clean-up-dma-timeout-handling.patch
> hpt3xx-init-code-rewrite.patch
> piix-fix-82371mx-enablebits.patch
> piix-tuneproc-fixes-cleanups.patch
> slc90e66-carry-over-fixes-from-piix-driver.patch
> hpt36x-pci-clock-detection-fix.patch
> jmicron-warning-fix.patch
> 	-- fixes (but most have cleanups mixed in)

    Yeah, but not that those came in from the -mm tree.

> pdc202xx_new-remove-useless-code.patch
> pdc202xx_-remove-check_in_drive_lists-abomination.patch
> 	-- cleanups
> #
> # IDE patches applied by Andrew (2.6.20-rc4-mm1)
> #
> atiixpc-remove-unused-code.patch
> 	-- cleanup
> atiixpc-sb600-ide-only-has-one-channel.patch
> atiixpc-add-cable-detection-support-for-ati-ide.patch
> ide-generic-jmicron-has-its-own-drivers-now.patch
> 	-- fixes

    Same about these 3.

> ide-maintainers-entry.patch
> 	-- n/a
> #
> # IT8213
> #
> it8213-ide-driver.patch
> it8213-ide-driver-update.patch
> 	-- new driver
> #
> # patches posted on Jan 11 2007
> #
> ia64-pci_get_legacy_ide_irq.patch
> ide-pci-init-tags.patch
> 	-- fixes
> pdc202xx_old-dead-code.patch
> au1xxx-dead-code.patch
> ide-pio-blacklisted.patch
> ide-no-dsc-flag.patch
> trm290-dma-ifdefs.patch
> ide-pci-device-tables.patch
> ide-dev-openers.patch
> hpt366-init-dma.patch
> cs5530-cleanup.patch
> svwks-cleanup.patch
> sis5513-config-xfer-rate.patch
> ide-set-xfer-rate.patch
> ide-use-fast-pio-v2.patch
> ide-io-cleanup.patch
> 	-- cleanups
> #
> # Delkin CardBus CF driver (Mark Lord <mlord@pobox.com>)
> #
> delkin_cb-ide-driver.patch
> 	-- new driver
> #
> # IDE ACPI support (Hannes Reinecke <hare@suse.de>)
> #
> ide-acpi-support.patch
> 	-- new functionality (fixes PM on some machines)
> #
> # ide-pnp exit fix (Tejun Heo <htejun@gmail.com>)
> #
> ide-pnp-exit-fix.patch
> 	-- fix
> #
> # VIA IDE update (Josepch Chan <josephchan@via.com.tw>)
> #
> via-ide-update.patch
> 	-- fix

    I'd put fixes before the rewrites and new code...

> #
> # patches posted on 18 Jan 2007
> #
> it8213-ide-driver-update-fixes.patch
> 	-- fix

    Well, this is a fix to the newly added driver, so may go anywhere after it...

> ide-mmio-flag.patch
> 	-- cleanup
> hpt34x-tune-chipset-fix.patch
> 	-- fix
> ide-fix-pio-fallback.patch
> 	-- fix

    Those 2 are seem more of a cleanup to me...

> piix-cleanup.patch
> 	-- cleanup
> ide-dma-check-disable-dma-fix.patch
> sgiioc4-ide-dma-check-fix.patch
> 	-- fixes

    This one also seems more of a cleanup...

> ide-set-dma-helper.patch
> ide-dma-off-void.patch
> ide-dma-host-on-void.patch
> ide-fix-dma-masks.patch
> ide-max-dma-mode.patch
> ide-tune-dma-helper.patch
> 	-- cleanups

    Would make sense to keep those last in the tail of queue because of the
amount of changes they introduce.  Possibly even IDE subsystem wide cleanups 
after the driver specific cleanups, although this is arguable...

> So it looks more like 50-50 with majority of fixes coming from you :)

> However I understand that for some applications (stable distro etc) fixes
> only tree would be more desired

    Yeah, I'm really not eager to pull in the ton of cleanups for a couple of 
fixes which won't apply otherwise (or have to rebase the fixes because of that).

> and if somebody would like to maintain such tree I'm all for it. :)

    Well, we have the -mm tree. :-)
    I certainly have no time/bandwidth to spend on maintaining a tree, at
least for the moment being.

> OTOH getting patches against vanilla or -mm is perfectly fine with me

    Thanks. Will send further patches to you only, not Andrew (with the notice 
of the kernel they should apply to).

> and if you would like me to shuffle ordering of the patches (but without
> need of rewritting them) it also OK

    Erm, no talking about the rewrite but that way you may have to rebase 
cleanups on top of fixes.  This seems unavoidble though due to the way the 
kernel patch acceptance process is working, as far as I understand it...

>>>>>Index: b/drivers/ide/pci/cmd64x.c
>>>>>===================================================================
>>>>>--- a/drivers/ide/pci/cmd64x.c
>>>>>+++ b/drivers/ide/pci/cmd64x.c
>>>>>@@ -479,12 +479,10 @@ static int cmd64x_config_drive_for_dma (
>>>>>     if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>>>>             return hwif->ide_dma_on(drive);
>>>>>
>>>>>-     if (ide_use_fast_pio(drive)) {
>>>>>+     if (ide_use_fast_pio(drive))
>>>>>             config_chipset_for_pio(drive, 1);

>>>>  This function will always set PIO mode 4. Mess.

>>>Yep.

>>   I'm going to send the patch for both this and siimage.c...

> OK

    Not sure if I'll be able to find a card to test it soon though (I prefer 
to test my stuff before submitting, even the simple changes :-).

>>>>>Index: b/drivers/ide/pci/sis5513.c
>>>>>===================================================================
>>>>>--- a/drivers/ide/pci/sis5513.c
>>>>>+++ b/drivers/ide/pci/sis5513.c
>>>>>@@ -678,12 +678,10 @@ static int sis5513_config_xfer_rate(ide_
>>>>>     if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>>>>             return hwif->ide_dma_on(drive);

>>>>>-     if (ide_use_fast_pio(drive)) {
>>>>>+     if (ide_use_fast_pio(drive))
>>>>>             sis5513_tune_drive(drive, 5);

>>>>   Ugh, PIO fallback effectively always tries to set mode 4 here (thanks
>>>>it's not 5). Mess.

>>>Yep, but it seems to be even more complicated since config_art_rwp_pio()
>>>is a mess^2 - chipset is programmed to the best PIO mode while the
>>>device is set to PIO4... *sigh*...

    Oh, that's an usual mistake all over drivers/ide/pci/. :-)

> Bart

MBR, Sergei


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

* Re: [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case
       [not found]                 ` <58cb370e0701200947p578f4d74g1fee511ded6c9a77@mail.gmail.com>
@ 2007-01-20 18:21                   ` Bartlomiej Zolnierkiewicz
  2007-01-20 18:41                     ` Sergei Shtylyov
  2007-01-25 17:03                     ` Sergei Shtylyov
  0 siblings, 2 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-01-20 18:21 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-ide, linux-kernel


Hi,

Sergei Shtylyov wrote:
> Bartlomiej Zolnierkiewicz wrote:
> 
>>>>>  I've looked thru the code, and found more issues with the PIO fallback
>>>>> there. Will try to cook up patches for at least some drivers...
> 
>>>> Great, if possible please base them on top of the IDE tree...
> 
>>>   Erm, I had doubts about it (having in mind that all that code is more of a
>>> cleanups than fixes). Maybe it'd be a good idea to separate the fix and
>>> cleanup series somehow...
> 
>> I generally tend do cleanups as a groundwork for the real fixes and separate
>> cleanups and fixes to have good base for dealing with regressions.  Often all
>> changes (cleanups/fixes) could be included in one patch but then I would have
>> had harsh times when debugging the regressions.  It matters a lot if you hit
>> an unknown (or known but the documentation is covered by NDA) hardware bug
>> - you can concentrate on a small patch changing the way in which hardware is
>> accessed instead of that big patch moving code around etc.
> 
>> Also the thing is that the same bugs are propagated over many drivers so doing
>> cleanups which merge code before fixing the bug makes sense.  We can then fix
>> the damn bug once and for all and not worry about somebody copy-n-pasting
>> the bug from the yet-to-be-fixed driver (i.e. in the next patch IDE update
>> there will be patch to check return value of ->speedproc in ide_tune_dma(),
>> without ide-fix-dma-mask/ide-max-dma-mode/ide-tune-dma-helper patches
>> I would have to go over all drivers to fix this bug and still there won't
>> be a guarantee that same bug wouldn't be introduced in some new driver).
> 
>> The other advantage of doing cleanups is that code becomes cleaner/simpler
>> which matters a lot for this codebase, i.e. ide-dma-off-void.patch exposed
>> (yet to be fixed) bug in set_using_dma() (->ide_dma_off_quietly always returns
>> 0 which is passed by ->ide_dma_check to set_using_dma() which incorrectly
>> then calls ->ide_dma_on).
> 
>    Well, this seems a newly intruduced bug.

The old code is so convulted that it is hard to see it w/o cleanup. :)

->ide_dma_check implementations often do

		return hwif->ide_dma_off_quietly(drive);

so the return value of ide_dma_off_quietly() (which is always 0) is passed to

			if (HWIF(drive)->ide_dma_check(drive)) return -EIO;

in ide.c:set_using_dma() -> as a result the next line is executed

			if (HWIF(drive)->ide_dma_on(drive)) return -EIO;

>    It's all fine but goes somewhat against Linus' policy as far as I
> understnad it: fixes are merged all the time while cleanups (along with new
> code) are merged mostly duting the merge window.
> 
>> Moreover I don't find the current tree to be more of cleanups than fixes,
>> here is the analysis of current series file:
> 
>    Maybe I slightly exaggerated, being impressed by the volume of your recent
> changes. :-)
>    But still...
> 
>> #
>> # IDE patches from 2.6.20-rc3-mm1
>> #
>> toshiba-tc86c001-ide-driver-take-2.patch
>> toshiba-tc86c001-ide-driver-take-2-fix.patch
>> toshiba-tc86c001-ide-driver-take-2-fix-2.patch
>>       -- new driver
> 
>     I'd count that as cleanup, since it's definitely not fix. ;-)
> 
>> hpt3xx-rework-rate-filtering.patch
>> hpt3xx-rework-rate-filtering-tidy.patch
>> hpt3xx-print-the-real-chip-name-at-startup.patch
>> hpt3xx-switch-to-using-pci_get_slot.patch
>> hpt3xx-cache-channels-mcr-address.patch
>> hpt3x7-merge-speedproc-handlers.patch
>> hpt370-clean-up-dma-timeout-handling.patch
>> hpt3xx-init-code-rewrite.patch
>> piix-fix-82371mx-enablebits.patch
>> piix-tuneproc-fixes-cleanups.patch
>> slc90e66-carry-over-fixes-from-piix-driver.patch
>> hpt36x-pci-clock-detection-fix.patch
>> jmicron-warning-fix.patch
>>       -- fixes (but most have cleanups mixed in)
> 
>    Yeah, but not that those came in from the -mm tree.
> 
>> pdc202xx_new-remove-useless-code.patch
>> pdc202xx_-remove-check_in_drive_lists-abomination.patch
>>       -- cleanups
>> #
>> # IDE patches applied by Andrew (2.6.20-rc4-mm1)
>> #
>> atiixpc-remove-unused-code.patch
>>       -- cleanup
>> atiixpc-sb600-ide-only-has-one-channel.patch
>> atiixpc-add-cable-detection-support-for-ati-ide.patch
>> ide-generic-jmicron-has-its-own-drivers-now.patch
>>       -- fixes
> 
>    Same about these 3.
> 
>> ide-maintainers-entry.patch
>>       -- n/a
>> #
>> # IT8213
>> #
>> it8213-ide-driver.patch
>> it8213-ide-driver-update.patch
>>       -- new driver
>> #
>> # patches posted on Jan 11 2007
>> #
>> ia64-pci_get_legacy_ide_irq.patch
>> ide-pci-init-tags.patch
>>       -- fixes
>> pdc202xx_old-dead-code.patch
>> au1xxx-dead-code.patch
>> ide-pio-blacklisted.patch
>> ide-no-dsc-flag.patch
>> trm290-dma-ifdefs.patch
>> ide-pci-device-tables.patch
>> ide-dev-openers.patch
>> hpt366-init-dma.patch
>> cs5530-cleanup.patch
>> svwks-cleanup.patch
>> sis5513-config-xfer-rate.patch
>> ide-set-xfer-rate.patch
>> ide-use-fast-pio-v2.patch
>> ide-io-cleanup.patch
>>       -- cleanups
>> #
>> # Delkin CardBus CF driver (Mark Lord <mlord@pobox.com>)
>> #
>> delkin_cb-ide-driver.patch
>>       -- new driver
>> #
>> # IDE ACPI support (Hannes Reinecke <hare@suse.de>)
>> #
>> ide-acpi-support.patch
>>       -- new functionality (fixes PM on some machines)
>> #
>> # ide-pnp exit fix (Tejun Heo <htejun@gmail.com>)
>> #
>> ide-pnp-exit-fix.patch
>>       -- fix
>> #
>> # VIA IDE update (Josepch Chan <josephchan@via.com.tw>)
>> #
>> via-ide-update.patch
>>       -- fix
> 
>    I'd put fixes before the rewrites and new code...

OK, I'll shuffle the patches.

[ + I want to put it to Linus ASAP ]

>> #
>> # patches posted on 18 Jan 2007
>> #
>> it8213-ide-driver-update-fixes.patch
>>       -- fix
> 
>    Well, this is a fix to the newly added driver, so may go anywhere
> after it...

OK.

>> ide-mmio-flag.patch
>>       -- cleanup
>> hpt34x-tune-chipset-fix.patch
>>       -- fix
>> ide-fix-pio-fallback.patch
>>       -- fix
> 
>    Those 2 are seem more of a cleanup to me...

They fix real but quite hard to hit bugs.
I'll put them at the end of the fixes series.

>> piix-cleanup.patch
>>       -- cleanup
>> ide-dma-check-disable-dma-fix.patch
>> sgiioc4-ide-dma-check-fix.patch
>>       -- fixes
> 
>    This one also seems more of a cleanup...

ditto

>> ide-set-dma-helper.patch
>> ide-dma-off-void.patch
>> ide-dma-host-on-void.patch
>> ide-fix-dma-masks.patch
>> ide-max-dma-mode.patch
>> ide-tune-dma-helper.patch
>>       -- cleanups
> 
>    Would make sense to keep those last in the tail of queue because of the
> amount of changes they introduce.  Possibly even IDE subsystem wide cleanups

They are at the end already - no problem here. :)

> after the driver specific cleanups, although this is arguable...

Yep, makes sense.

>> So it looks more like 50-50 with majority of fixes coming from you :)
> 
>> However I understand that for some applications (stable distro etc) fixes
>> only tree would be more desired
> 
>    Yeah, I'm really not eager to pull in the ton of cleanups for a couple of
> fixes which won't apply otherwise (or have to rebase the fixes because of that).
> 
>> and if somebody would like to maintain such tree I'm all for it. :)
> 
>    Well, we have the -mm tree. :-)
> 
>    I certainly have no time/bandwidth to spend on maintaining a tree, at
> least for the moment being.
> 
>> OTOH getting patches against vanilla or -mm is perfectly fine with me
> 
>    Thanks. Will send further patches to you only, not Andrew (with the notice
> of the kernel they should apply to).

OK, thanks.

>> and if you would like me to shuffle ordering of the patches (but without
>> need of rewritting them) it also OK
> 
>    Erm, no talking about the rewrite but that way you may have to rebase
> cleanups on top of fixes.  This seems unavoidble though due to the way the
> kernel patch acceptance process is working, as far as I understand it...

I'll change the ordering of the patches based on your suggestions
and generally try to keep such order of fixes first and cleanups later.

With systematic and frequent syncing with mainstream keeping this order
should be even less of problem.

>>>>>> Index: b/drivers/ide/pci/cmd64x.c
>>>>>> ===================================================================
>>>>>> --- a/drivers/ide/pci/cmd64x.c
>>>>>> +++ b/drivers/ide/pci/cmd64x.c
>>>>>> @@ -479,12 +479,10 @@ static int cmd64x_config_drive_for_dma (
>>>>>>     if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>>>>>             return hwif->ide_dma_on(drive);
>>>>>>
>>>>>> -     if (ide_use_fast_pio(drive)) {
>>>>>> +     if (ide_use_fast_pio(drive))
>>>>>>             config_chipset_for_pio(drive, 1);
> 
>>>>>  This function will always set PIO mode 4. Mess.
> 
>>>> Yep.
> 
>>>   I'm going to send the patch for both this and siimage.c...
> 
>> OK
> 
>    Not sure if I'll be able to find a card to test it soon though (I prefer
> to test my stuff before submitting, even the simple changes :-).

Please send it anyway.

Thanks,
Bart

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

* Re: [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case
  2007-01-20 18:21                   ` Bartlomiej Zolnierkiewicz
@ 2007-01-20 18:41                     ` Sergei Shtylyov
  2007-01-25 17:03                     ` Sergei Shtylyov
  1 sibling, 0 replies; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-20 18:41 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:

>>>The other advantage of doing cleanups is that code becomes cleaner/simpler
>>>which matters a lot for this codebase, i.e. ide-dma-off-void.patch exposed
>>>(yet to be fixed) bug in set_using_dma() (->ide_dma_off_quietly always returns
>>>0 which is passed by ->ide_dma_check to set_using_dma() which incorrectly
>>>then calls ->ide_dma_on).

>>   Well, this seems a newly intruduced bug.

> The old code is so convulted that it is hard to see it w/o cleanup. :)

> ->ide_dma_check implementations often do

> 		return hwif->ide_dma_off_quietly(drive);

> so the return value of ide_dma_off_quietly() (which is always 0) is passed to

> 			if (HWIF(drive)->ide_dma_check(drive)) return -EIO;

> in ide.c:set_using_dma() -> as a result the next line is executed

> 			if (HWIF(drive)->ide_dma_on(drive)) return -EIO;

    Ah, indeed! Nice. :-)

>>   It's all fine but goes somewhat against Linus' policy as far as I
>>understnad it: fixes are merged all the time while cleanups (along with new
>>code) are merged mostly duting the merge window.

>>>Moreover I don't find the current tree to be more of cleanups than fixes,
>>>here is the analysis of current series file:

>>   Maybe I slightly exaggerated, being impressed by the volume of your recent
>>changes. :-)
>>   But still...

>>>#
>>># IDE patches from 2.6.20-rc3-mm1
>>>#
>>>toshiba-tc86c001-ide-driver-take-2.patch
>>>toshiba-tc86c001-ide-driver-take-2-fix.patch
>>>toshiba-tc86c001-ide-driver-take-2-fix-2.patch
>>>      -- new driver

>>    I'd count that as cleanup, since it's definitely not fix. ;-)

>>>hpt3xx-rework-rate-filtering.patch
>>>hpt3xx-rework-rate-filtering-tidy.patch
>>>hpt3xx-print-the-real-chip-name-at-startup.patch
>>>hpt3xx-switch-to-using-pci_get_slot.patch
>>>hpt3xx-cache-channels-mcr-address.patch
>>>hpt3x7-merge-speedproc-handlers.patch
>>>hpt370-clean-up-dma-timeout-handling.patch
>>>hpt3xx-init-code-rewrite.patch
>>>piix-fix-82371mx-enablebits.patch
>>>piix-tuneproc-fixes-cleanups.patch
>>>slc90e66-carry-over-fixes-from-piix-driver.patch
>>>hpt36x-pci-clock-detection-fix.patch
>>>jmicron-warning-fix.patch
>>>      -- fixes (but most have cleanups mixed in)

>>   Yeah, but not that those came in from the -mm tree.

    Oops, "not that" didn't make sense here :-)

>>>ide-mmio-flag.patch
>>>      -- cleanup
>>>hpt34x-tune-chipset-fix.patch
>>>      -- fix
>>>ide-fix-pio-fallback.patch
>>>      -- fix

>>   Those 2 are seem more of a cleanup to me...

> They fix real but quite hard to hit bugs.
> I'll put them at the end of the fixes series.

    Well, most of the recent fixes were for such issues.  Nobody had screamed 
about them, it took a code review to find them. :-)

>>>ide-set-dma-helper.patch
>>>ide-dma-off-void.patch
>>>ide-dma-host-on-void.patch
>>>ide-fix-dma-masks.patch
>>>ide-max-dma-mode.patch
>>>ide-tune-dma-helper.patch
>>>      -- cleanups

>>   Would make sense to keep those last in the tail of queue because of the
>>amount of changes they introduce.  Possibly even IDE subsystem wide cleanups

> They are at the end already - no problem here. :)

    I meant "in the future"...

>>>and if you would like me to shuffle ordering of the patches (but without
>>>need of rewritting them) it also OK

>>   Erm, no talking about the rewrite but that way you may have to rebase
>>cleanups on top of fixes.  This seems unavoidble though due to the way the
>>kernel patch acceptance process is working, as far as I understand it...

> I'll change the ordering of the patches based on your suggestions
> and generally try to keep such order of fixes first and cleanups later.

    Thanks. :-)

>>>>>>>Index: b/drivers/ide/pci/cmd64x.c
>>>>>>>===================================================================
>>>>>>>--- a/drivers/ide/pci/cmd64x.c
>>>>>>>+++ b/drivers/ide/pci/cmd64x.c
>>>>>>>@@ -479,12 +479,10 @@ static int cmd64x_config_drive_for_dma (
>>>>>>>    if (ide_use_dma(drive) && config_chipset_for_dma(drive))
>>>>>>>            return hwif->ide_dma_on(drive);

>>>>>>>-     if (ide_use_fast_pio(drive)) {
>>>>>>>+     if (ide_use_fast_pio(drive))
>>>>>>>            config_chipset_for_pio(drive, 1);

>>>>>> This function will always set PIO mode 4. Mess.

>>>>>Yep.

>>>>  I'm going to send the patch for both this and siimage.c...

>>>OK

>>   Not sure if I'll be able to find a card to test it soon though (I prefer
>>to test my stuff before submitting, even the simple changes :-).

> Please send it anyway.

    Ugh, this one is more tough than pdc202xx_old.c -- since tuneproc() is 
also borken (doesn't set drive's own transfer mode).
    And... I looked into speedproc() handler, then into PCI0646U datasheet for 
reference and was really terrified: the code for SW/DW DMA setup us utter 
nonsense!  It writes to some reserved bits of BMIDE status reg. instead of 
doinf the real setup, and twiddles the drive 0/1 DMA capable bit which nobody 
asks it to do... Really messy mess. :-(

> Thanks,
> Bart

WBR, Sergei

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

* Re: [PATCH 10/15] ide: add ide_set_dma() helper
  2007-01-19  0:32 ` [PATCH 10/15] ide: add ide_set_dma() helper Bartlomiej Zolnierkiewicz
@ 2007-01-20 20:22   ` Sergei Shtylyov
  0 siblings, 0 replies; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-20 20:22 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello again. :-)

Bartlomiej Zolnierkiewicz wrote:
> [PATCH] ide: add ide_set_dma() helper

> * add ide_set_dma() helper and make ide_hwif_t.ide_dma_check return
>   -1 when DMA needs to be disabled (== need to call ->ide_dma_off_quietly)
>    0 when DMA needs to be enabled  (== need to call ->ide_dma_on)
>    1 when DMA setting shouldn't be changed
> * fix IDE code to use ide_set_dma() instead if using ->ide_dma_check directly

    Here are a few comments related to the code being patched:

> Index: b/drivers/ide/pci/alim15x3.c
> ===================================================================
> --- a/drivers/ide/pci/alim15x3.c
> +++ b/drivers/ide/pci/alim15x3.c
> @@ -507,17 +507,15 @@ static int config_chipset_for_dma (ide_d
>   *
>   *	Configure a drive for DMA operation. If DMA is not possible we
>   *	drop the drive into PIO mode instead.
> - *
> - *	FIXME: exactly what are we trying to return here
>   */
> - 
> +
>  static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
>  {
>  	ide_hwif_t *hwif	= HWIF(drive);
>  	struct hd_driveid *id	= drive->id;
>  
>  	if ((m5229_revision<=0x20) && (drive->media!=ide_disk))
> -		return hwif->ide_dma_off_quietly(drive);
> +		goto no_dma_set;

    Isn't it better to just return -1?

> @@ -552,9 +550,10 @@ try_dma_modes:
>  ata_pio:
>  		hwif->tuneproc(drive, 255);
>  no_dma_set:
> -		return hwif->ide_dma_off_quietly(drive);
> +		return -1;
>  	}
> -	return hwif->ide_dma_on(drive);
> +
> +	return 0;
>  }

    Ugh, this code looks like it's asking to be converted into calling 
ide_use_dma(). instead all of that...

> Index: b/drivers/ide/pci/cs5520.c
> ===================================================================
> --- a/drivers/ide/pci/cs5520.c
> +++ b/drivers/ide/pci/cs5520.c
> @@ -132,12 +132,11 @@ static void cs5520_tune_drive(ide_drive_
>  
>  static int cs5520_config_drive_xfer_rate(ide_drive_t *drive)
>  {
> -	ide_hwif_t *hwif = HWIF(drive);
> -
>  	/* Tune the drive for PIO modes up to PIO 4 */	
>  	cs5520_tune_drive(drive, 4);

    Ugh. Why not ask drive? :-/

>  	/* Then tell the core to use DMA operations */
> -	return hwif->ide_dma_on(drive);
> +	return 0;

    That must be the famous VDMA thing... :-)
    I wonder if it *actually* works on HPT36x/37x which seem to have support 
for it...

> Index: b/drivers/ide/pci/jmicron.c
> ===================================================================
> --- a/drivers/ide/pci/jmicron.c
> +++ b/drivers/ide/pci/jmicron.c
> @@ -164,14 +164,12 @@ static int config_chipset_for_dma (ide_d
>  
>  static int jmicron_config_drive_for_dma (ide_drive_t *drive)
>  {
> -	ide_hwif_t *hwif	= drive->hwif;
> +	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
> +		return 0;
>  
> -	if (ide_use_dma(drive)) {
> -		if (config_chipset_for_dma(drive))
> -			return hwif->ide_dma_on(drive);
> -	}
>  	config_jmicron_chipset_for_pio(drive, 1);

    The 2nd argument of that funtion is useless -- it basically does nothing 
if 0 is passed. Another case of mindless copy-paste. :-)

> Index: b/drivers/ide/pci/pdc202xx_old.c
> ===================================================================
> --- a/drivers/ide/pci/pdc202xx_old.c
> +++ b/drivers/ide/pci/pdc202xx_old.c
> @@ -332,17 +332,15 @@ chipset_is_set:
>  
>  static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive)
>  {
> -	ide_hwif_t *hwif	= HWIF(drive);
> -
>  	drive->init_speed = 0;
>  
>  	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
> -		return hwif->ide_dma_on(drive);
> +		return 0;
>  
>  	if (ide_use_fast_pio(drive))
> -		hwif->tuneproc(drive, 5);
> +		config_chipset_for_pio(drive, 5);

    That part is obsoleted by my recent fix...

> Index: b/drivers/ide/pci/piix.c
> ===================================================================
> --- a/drivers/ide/pci/piix.c
> +++ b/drivers/ide/pci/piix.c
> @@ -386,20 +386,18 @@ static int piix_config_drive_for_dma (id
>   
>  static int piix_config_drive_xfer_rate (ide_drive_t *drive)
>  {
> -	ide_hwif_t *hwif	= HWIF(drive);
> -
>  	drive->init_speed = 0;
>  
>  	if (ide_use_dma(drive) && piix_config_drive_for_dma(drive))
> -		return hwif->ide_dma_on(drive);
> +		return 0;
>  
>  	if (ide_use_fast_pio(drive)) {
>  		/* Find best PIO mode. */
> -		(void) hwif->speedproc(drive, XFER_PIO_0 +
> -				       ide_get_best_pio_mode(drive, 255, 4, NULL));
> +		u8 pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
> +		(void)piix_tune_chipset(drive, XFER_PIO_0 + pio);
>  	}

    Will try to fix the tuneproc() nuisance RSN. :-)

> Index: b/drivers/ide/pci/serverworks.c
> ===================================================================
> --- a/drivers/ide/pci/serverworks.c
> +++ b/drivers/ide/pci/serverworks.c
> @@ -315,17 +315,15 @@ static int config_chipset_for_dma (ide_d
>  
>  static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
>  {
> -	ide_hwif_t *hwif	= HWIF(drive);
> -
>  	drive->init_speed = 0;
>  
>  	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
> -		return hwif->ide_dma_on(drive);
> +		return 0;
>  
>  	if (ide_use_fast_pio(drive))
>  		config_chipset_for_pio(drive);

    I have no idea why that function is so huge in this driver, i.e. why all 
this code is not in svwks_tune_chipset()...

> -	return hwif->ide_dma_off_quietly(drive);
> +	return -1;
>  }
>  
>  static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const char *name)
> Index: b/drivers/ide/pci/sl82c105.c
> ===================================================================
> --- a/drivers/ide/pci/sl82c105.c
> +++ b/drivers/ide/pci/sl82c105.c
> @@ -161,14 +161,14 @@ static int sl82c105_check_drive (ide_dri
>  		if (id->field_valid & 2) {
>  			if ((id->dma_mword & hwif->mwdma_mask) ||
>  			    (id->dma_1word & hwif->swdma_mask))

    Ugh. This driver claims the full MW/SW DMA support while actually only 
supports MWDMA2.

> -				return hwif->ide_dma_on(drive);
> +				return 0;
>  		}
>  
>  		if (__ide_dma_good_drive(drive))
> -			return hwif->ide_dma_on(drive);
> +			return 0;
>  	} while (0);

    This also asks to be converted into ide_use_dma() call. The patch is 
cooking...

> -	return hwif->ide_dma_off_quietly(drive);
> +	return -1;
>  }
>  
>  /*
> Index: b/drivers/ide/pci/slc90e66.c
> ===================================================================
> --- a/drivers/ide/pci/slc90e66.c
> +++ b/drivers/ide/pci/slc90e66.c
> @@ -179,19 +179,17 @@ static int slc90e66_config_drive_for_dma
>  
>  static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
>  {
> -	ide_hwif_t *hwif	= HWIF(drive);
> -
>  	drive->init_speed = 0;
>  
>  	if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
> -		return hwif->ide_dma_on(drive);
> +		return 0;
>  
>  	if (ide_use_fast_pio(drive)) {
> -		(void) hwif->speedproc(drive, XFER_PIO_0 +
> -				       ide_get_best_pio_mode(drive, 255, 4, NULL));
> +		u8 pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
> +		(void)slc90e66_tune_chipset(drive, XFER_PIO_0 + pio);
>  	}

    The same promise about tuneproc() in this driver... :-)

MBR, Sergei

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

* Re: [PATCH 12/15] ide: make ide_hwif_t.ide_dma_host_on void
  2007-01-19  0:32 ` [PATCH 12/15] ide: make ide_hwif_t.ide_dma_host_on void Bartlomiej Zolnierkiewicz
@ 2007-01-20 20:46   ` Sergei Shtylyov
       [not found]     ` <58cb370e0702021128g15cac87ar507c20e78ded9464@mail.gmail.com>
  2007-03-26 17:19   ` Sergei Shtylyov
  1 sibling, 1 reply; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-20 20:46 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello again. :-)

Bartlomiej Zolnierkiewicz wrote:

> [PATCH] ide: make ide_hwif_t.ide_dma_host_on void

> * since ide_hwif_t.ide_dma_host_on is called either when drive->using_dma == 1
>   or when return value is discarded make it void, also drop "ide_" prefix
> * make __ide_dma_host_on() void and drop "__" prefix

    Below are some nits which also apply to the previous patch...

> Index: b/drivers/ide/pci/atiixp.c
> ===================================================================
> --- a/drivers/ide/pci/atiixp.c
> +++ b/drivers/ide/pci/atiixp.c
> @@ -101,7 +101,7 @@ static u8 atiixp_dma_2_pio(u8 xfer_rate)
>  	}
>  }
>  
> -static int atiixp_ide_dma_host_on(ide_drive_t *drive)
> +static void atiixp_ide_dma_host_on(ide_drive_t *drive)
>  {

    Would seem logical to get rid of ide_ in this function's name also...

>  	struct pci_dev *dev = drive->hwif->pci_dev;
>  	unsigned long flags;
[...]
> Index: b/drivers/ide/pci/sgiioc4.c
> ===================================================================
> --- a/drivers/ide/pci/sgiioc4.c
> +++ b/drivers/ide/pci/sgiioc4.c
[...]
> @@ -307,13 +307,8 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * d
>  	return sgiioc4_checkirq(HWIF(drive));
>  }
>  
> -static int
> -sgiioc4_ide_dma_host_on(ide_drive_t * drive)
> +static void sgiioc4_ide_dma_host_on(ide_drive_t * drive)

    Same comment here...

>  {
> -	if (drive->using_dma)
> -		return 0;
> -
> -	return 1;
>  }
>  
>  static void sgiioc4_ide_dma_host_off(ide_drive_t * drive)
> @@ -610,7 +605,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
>  	hwif->ide_dma_on = &sgiioc4_ide_dma_on;
>  	hwif->dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
>  	hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
> -	hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
> +	hwif->dma_host_on = &sgiioc4_ide_dma_host_on;
>  	hwif->dma_host_off = &sgiioc4_ide_dma_host_off;
>  	hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
>  	hwif->ide_dma_timeout = &__ide_dma_timeout;

    Unrelated note: not sure why this default value needs explicit assignemnt...

MBR, Sergei

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

* Re: [PATCH 11/15] ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void
  2007-01-19  0:32 ` [PATCH 11/15] ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void Bartlomiej Zolnierkiewicz
@ 2007-01-20 20:56   ` Sergei Shtylyov
       [not found]     ` <58cb370e0702021206h205ff983r88fb4bdbea42ed9f@mail.gmail.com>
  0 siblings, 1 reply; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-20 20:56 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello again. :-)

Bartlomiej Zolnierkiewicz wrote:

> [PATCH] ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void

    Below are my nits on the patch itself, and the code it changes.

> Index: b/drivers/ide/pci/atiixp.c
> ===================================================================
> --- a/drivers/ide/pci/atiixp.c
> +++ b/drivers/ide/pci/atiixp.c
> @@ -121,7 +121,7 @@ static int atiixp_ide_dma_host_on(ide_dr
>  	return __ide_dma_host_on(drive);
>  }
>  
> -static int atiixp_ide_dma_host_off(ide_drive_t *drive)
> +static void atiixp_ide_dma_host_off(ide_drive_t *drive)
>  {
>  	struct pci_dev *dev = drive->hwif->pci_dev;
>  	unsigned long flags;
[...]
> @@ -306,7 +306,7 @@ static void __devinit init_hwif_atiixp(i
>  		hwif->udma_four = 0;
>  
>  	hwif->ide_dma_host_on = &atiixp_ide_dma_host_on;
> -	hwif->ide_dma_host_off = &atiixp_ide_dma_host_off;
> +	hwif->dma_host_off = &atiixp_ide_dma_host_off;
>  	hwif->ide_dma_check = &atiixp_dma_check;
>  	if (!noautodma)
>  		hwif->autodma = 1;

    Would seem logical to get rid of ide_ in the function's name also...

> Index: b/drivers/ide/pci/sgiioc4.c
> ===================================================================
> --- a/drivers/ide/pci/sgiioc4.c
> +++ b/drivers/ide/pci/sgiioc4.c
> @@ -282,12 +282,11 @@ sgiioc4_ide_dma_on(ide_drive_t * drive)
>  	return HWIF(drive)->ide_dma_host_on(drive);
>  }
>  
> -static int
> -sgiioc4_ide_dma_off_quietly(ide_drive_t * drive)
> +static void sgiioc4_ide_dma_off_quietly(ide_drive_t *drive)
>  {
>  	drive->using_dma = 0;
>  
> -	return HWIF(drive)->ide_dma_host_off(drive);
> +	drive->hwif->dma_host_off(drive);
>  }
>  
>  static int sgiioc4_ide_dma_check(ide_drive_t *drive)
> @@ -317,12 +316,9 @@ sgiioc4_ide_dma_host_on(ide_drive_t * dr
>  	return 1;
>  }
>  
> -static int
> -sgiioc4_ide_dma_host_off(ide_drive_t * drive)
> +static void sgiioc4_ide_dma_host_off(ide_drive_t * drive)
>  {
>  	sgiioc4_clearirq(drive);
> -
> -	return 0;
>  }
>  
>  static int
> @@ -612,10 +608,10 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
>  	hwif->ide_dma_end = &sgiioc4_ide_dma_end;
>  	hwif->ide_dma_check = &sgiioc4_ide_dma_check;
>  	hwif->ide_dma_on = &sgiioc4_ide_dma_on;
> -	hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
> +	hwif->dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
>  	hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
>  	hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
> -	hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
> +	hwif->dma_host_off = &sgiioc4_ide_dma_host_off;
>  	hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
>  	hwif->ide_dma_timeout = &__ide_dma_timeout;

    The same here...

> Index: b/drivers/ide/pci/sl82c105.c
> ===================================================================
> --- a/drivers/ide/pci/sl82c105.c
> +++ b/drivers/ide/pci/sl82c105.c
> @@ -261,26 +261,24 @@ static int sl82c105_ide_dma_on (ide_driv
>  
>  	if (config_for_dma(drive)) {
>  		config_for_pio(drive, 4, 0, 0);

   Ugh, this forces PIO4 on fallback... and dma_on() doesn't select any modes 
in any other driver but this one. :-/

> -		return HWIF(drive)->ide_dma_off_quietly(drive);
> +		drive->hwif->dma_off_quietly(drive);
> +		return 0;
>  	}
>  	printk(KERN_INFO "%s: DMA enabled\n", drive->name);
>  	return __ide_dma_on(drive);
>  }
>  
> -static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive)
> +static void sl82c105_ide_dma_off_quietly(ide_drive_t *drive)

    Also worth renaming...

>  {
>  	u8 speed = XFER_PIO_0;
> -	int rc;
> -	
> +
>  	DBG(("sl82c105_ide_dma_off_quietly(drive:%s)\n", drive->name));
>  
> -	rc = __ide_dma_off_quietly(drive);
> +	ide_dma_off_quietly(drive);
>  	if (drive->pio_speed)

    Should always be non-zero since explicitly initialized.

>  		speed = drive->pio_speed - XFER_PIO_0;
>  	config_for_pio(drive, speed, 0, 1);
>  	drive->current_speed = drive->pio_speed;

    dma_off() shouldn't be changing current_speed IMHO.

> -
> -	return rc;
>  }

    The patch to fix those two functions is also cooking...

MBR, Sergei


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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-01-19  0:32 ` [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks Bartlomiej Zolnierkiewicz
@ 2007-01-22 16:19   ` Sergei Shtylyov
       [not found]     ` <58cb370e0702021606v4efa6143lf060e6aab9782c35@mail.gmail.com>
  2007-01-22 18:17   ` Sergei Shtylyov
  1 sibling, 1 reply; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-22 16:19 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:

> [PATCH] ide: fix UDMA/MWDMA/SWDMA masks

> * use 0x00 instead of 0x80 to disable ->{ultra,mwdma,swdma}_mask
> * add udma_mask field to ide_pci_device_t and use it to initialize
>   ->ultra_mask in aec62xx, pdc202xx_new and pdc202xx_old drivers
> * fix UDMA masks to match with chipset specific *_ratemask()
>   (alim15x3, hpt366, serverworks and siimage drivers need UDMA mask
>    filtering method - done in the next patch)

    More nit picking (-:

> Index: b/drivers/ide/pci/cmd64x.c
> ===================================================================
> --- a/drivers/ide/pci/cmd64x.c
> +++ b/drivers/ide/pci/cmd64x.c
> @@ -695,9 +695,10 @@ static void __devinit init_hwif_cmd64x(i
>  	hwif->swdma_mask = 0x07;
>  
>  	if (dev->device == PCI_DEVICE_ID_CMD_643)
> -		hwif->ultra_mask = 0x80;
> +		hwif->ultra_mask = 0x00;
>  	if (dev->device == PCI_DEVICE_ID_CMD_646)
> -		hwif->ultra_mask = (class_rev > 0x04) ? 0x07 : 0x80;
> +		hwif->ultra_mask =
> +			(class_rev == 0x05 || class_rev == 0x07) ? 0x07 : 0x00;
>  	if (dev->device == PCI_DEVICE_ID_CMD_648)
>  		hwif->ultra_mask = 0x1f;

    Hm, well, this doesn't look consistent with the changes in other drivers.
This driver asks for explicit hwif->cds->ultra_mask initializers, IMO...
    You'd only have to check for PCI-646 revisions < 5 then...

> Index: b/drivers/ide/pci/piix.c
> ===================================================================
> --- a/drivers/ide/pci/piix.c
> +++ b/drivers/ide/pci/piix.c
> @@ -493,7 +493,7 @@ static void __devinit init_hwif_piix(ide
>  		case PCI_DEVICE_ID_INTEL_82371FB_0:
>  		case PCI_DEVICE_ID_INTEL_82371FB_1:
>  		case PCI_DEVICE_ID_INTEL_82371SB_1:
> -			hwif->ultra_mask = 0x80;
> +			hwif->ultra_mask = 0x00;
>  			break;
>  		case PCI_DEVICE_ID_INTEL_82371AB:
>  		case PCI_DEVICE_ID_INTEL_82443MX_1:
> @@ -501,6 +501,10 @@ static void __devinit init_hwif_piix(ide
>  		case PCI_DEVICE_ID_INTEL_82801AB_1:
>  			hwif->ultra_mask = 0x07;
>  			break;
> +		case PCI_DEVICE_ID_INTEL_82801AA_1:
> +		case PCI_DEVICE_ID_INTEL_82372FB_1:
> +			hwif->ultra_mask = 0x1f;
> +			break;

    Alas, I'm afraid this part is wrong!
    At least, the cable detection should work for 82801AA the same way as for 
the 82801Bx and newer chips, if Intel's datasheet is to be trusted... I think 
we should fall thru here.

>  		default:
>  			if (!hwif->udma_four)
>  				hwif->udma_four = piix_cable_detect(hwif);

    This one also certainly asks for explicit hwif->cds->ultra_mask 
initializers... Thus almost all of this switch statement could go away...

MBR, Sergei

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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-01-19  0:32 ` [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks Bartlomiej Zolnierkiewicz
  2007-01-22 16:19   ` Sergei Shtylyov
@ 2007-01-22 18:17   ` Sergei Shtylyov
  2007-01-22 18:46     ` Alan
       [not found]     ` <58cb370e0702021606m4eb6f682xfa4bf769d398cf9@mail.gmail.com>
  1 sibling, 2 replies; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-22 18:17 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:

> [PATCH] ide: fix UDMA/MWDMA/SWDMA masks

> * use 0x00 instead of 0x80 to disable ->{ultra,mwdma,swdma}_mask
> * add udma_mask field to ide_pci_device_t and use it to initialize
>   ->ultra_mask in aec62xx, pdc202xx_new and pdc202xx_old drivers
> * fix UDMA masks to match with chipset specific *_ratemask()
>   (alim15x3, hpt366, serverworks and siimage drivers need UDMA mask
>    filtering method - done in the next patch)

    More issues with aec62xx.c driver, found after looking at the next patch...

> Index: b/drivers/ide/pci/aec62xx.c
> ===================================================================
> --- a/drivers/ide/pci/aec62xx.c
> +++ b/drivers/ide/pci/aec62xx.c
> @@ -270,11 +270,13 @@ static unsigned int __devinit init_chips
>  
>  static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
>  {
> +	struct pci_dev *dev = hwif->pci_dev;
> +
>  	hwif->autodma = 0;
>  	hwif->tuneproc = &aec62xx_tune_drive;
>  	hwif->speedproc = &aec62xx_tune_chipset;
>  
> -	if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
> +	if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
>  		hwif->serialized = hwif->channel;
>  
>  	if (hwif->mate)
> @@ -286,7 +288,16 @@ static void __devinit init_hwif_aec62xx(
>  		return;
>  	}
>  
> -	hwif->ultra_mask = 0x7f;
> +	hwif->ultra_mask = hwif->cds->udma_mask;
> +
> +	/* atp865 and atp865r */
> +	if (hwif->ultra_mask == 0x3f) {
> +		unsigned long io = pci_resource_start(dev, 4);
> +
> +		if (inb(io) & 0x10)
> + 			hwif->ultra_mask = 0x7f; /* udma0-6 */
> +	}
> +

    Looks like another intruduced buglet: you're reading DMA command, but 
aec62xx_ratemask() was reading DMA status originally for this bit.

>  	hwif->mwdma_mask = 0x07;
>  	hwif->swdma_mask = 0x07;

    Hm, caught another nit: this driver doesn't actually support single-word 
DMA modes... :-)

> Index: b/drivers/ide/pci/alim15x3.c
> ===================================================================
> --- a/drivers/ide/pci/alim15x3.c
> +++ b/drivers/ide/pci/alim15x3.c
> @@ -765,8 +765,17 @@ static void __devinit init_hwif_common_a
>  
>  	hwif->atapi_dma = 1;
>  
> -	if (m5229_revision > 0x20)
> -		hwif->ultra_mask = 0x7f;
> +	if (m5229_revision <= 0x20)
> +		hwif->ultra_mask = 0x00; /* no udma */
> +	else if (m5229_revision < 0xC2)
> +		hwif->ultra_mask = 0x07; /* udma0-2 */
> +	else if (m5229_revision == 0xC2 || m5229_revision == 0xC3)
> +		hwif->ultra_mask = 0x1f; /* udma0-4 */
> +	else if (m5229_revision == 0xC4)
> +		hwif->ultra_mask = 0x3f; /* udma0-5 */
> +	else
> +		hwif->ultra_mask = 0x7f; /* udma0-6 */
> +
>  	hwif->mwdma_mask = 0x07;
>  	hwif->swdma_mask = 0x07;

    Ugh, I'm not seeing any *actual* support for MW/SW DMA in this driver... 
And PIO setting via speedproc() method is broken -- it passes to tuneproc() 
method mode number not biased by -XFER_PIO_0 beforehand.  Will cook up some 
patch, maybe... :-/

MBR, Sergei

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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-01-22 18:17   ` Sergei Shtylyov
@ 2007-01-22 18:46     ` Alan
  2007-01-22 20:28       ` Sergei Shtylyov
  2007-01-31 20:38       ` Sergei Shtylyov
       [not found]     ` <58cb370e0702021606m4eb6f682xfa4bf769d398cf9@mail.gmail.com>
  1 sibling, 2 replies; 48+ messages in thread
From: Alan @ 2007-01-22 18:46 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel

On Mon, 22 Jan 2007 21:17:33 +0300
>     Ugh, I'm not seeing any *actual* support for MW/SW DMA in this driver... 

Thats long been broken. Should be correct in the libata driver

Alan

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

* Re: [PATCH 14/15] ide: rework the code for selecting the best DMA transfer mode
  2007-01-19  0:32 ` [PATCH 14/15] ide: rework the code for selecting the best DMA transfer mode Bartlomiej Zolnierkiewicz
@ 2007-01-22 19:48   ` Sergei Shtylyov
       [not found]     ` <58cb370e0702021207o435f39cdsf3abb0d55829fc45@mail.gmail.com>
  0 siblings, 1 reply; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-22 19:48 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:

> [PATCH] ide: rework the code for selecting the best DMA transfer mode 

    Here's another portion of comments...

> Depends on the "ide: fix UDMA/MWDMA/SWDMA masks" patch.

> * add ide_hwif_t.filter_udma_mask hook for filtering UDMA mask

    Erm, maybe a shorter method name like udma_filter would go with the others 
better.  But well, that's my taste. :-)

>   (use it in alim15x3, hpt366, siimage and serverworks drivers)
> * add ide_max_dma_mode() for finding best DMA mode for the device
>   (loosely based on some older libata-core.c code)
> * convert ide_dma_speed() users to use ide_max_dma_mode()
> * make ide_rate_filter() take "ide_drive_t *drive" as an argument instead
>   of "u8 mode" and teach it to how to use UDMA mask to do filtering
> * use ide_rate_filter() in hpt366 driver
> * remove no longer needed ide_dma_speed() and *_ratemask()
> * unexport eighty_ninty_three()

> Index: b/drivers/ide/ide-dma.c
> ===================================================================
> --- a/drivers/ide/ide-dma.c
> +++ b/drivers/ide/ide-dma.c
> @@ -705,6 +705,80 @@ int ide_use_dma(ide_drive_t *drive)
>  
>  EXPORT_SYMBOL_GPL(ide_use_dma);
>  
> +static const u8 xfer_mode_bases[] = {
> +	XFER_UDMA_0,
> +	XFER_MW_DMA_0,
> +	XFER_SW_DMA_0,
> +};
> +
> +static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base)
> +{
> +	struct hd_driveid *id = drive->id;
> +	ide_hwif_t *hwif = drive->hwif;
> +	unsigned int mask = 0;
> +
> +	switch(base) {
> +	case XFER_UDMA_0:
> +		if ((id->field_valid & 4) == 0)
> +			break;
> +
> +		mask = id->dma_ultra & hwif->ultra_mask;
> +
> +		if (hwif->filter_udma_mask)
> +			mask &= hwif->filter_udma_mask(drive);
> +
> +		if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
> +			mask &= 0x07;
> +		break;
> +	case XFER_MW_DMA_0:
> +		mask = id->dma_mword & hwif->mwdma_mask;
> +		break;
> +	case XFER_SW_DMA_0:
> +		mask = id->dma_1word & hwif->swdma_mask;
> +		break;
> +	default:
> +		BUG();
> +		break;
> +	}
> +
> +	return mask;
> +}
> +
> +/**
> + *	ide_max_dma_mode	-	compute DMA speed
> + *	@drive: IDE device
> + *
> + *	Checks the drive capabilities and returns the speed to use
> + *	for the DMA transfer.  Returns 0 if the drive is incapable
> + *	of DMA transfers.
> + */
> +
> +u8 ide_max_dma_mode(ide_drive_t *drive)
> +{
> +	ide_hwif_t *hwif = drive->hwif;
> +	unsigned int mask;
> +	int x, i;
> +	u8 mode = 0;
> +
> +	if (drive->media != ide_disk && hwif->atapi_dma == 0)
> +		return 0;
> +
> +	for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) {
> +		mask = ide_get_mode_mask(drive, xfer_mode_bases[i]);
> +		x = fls(mask) - 1;
> +		if (x >= 0) {
> +			mode = xfer_mode_bases[i] + x;
> +			break;
> +		}
> +	}
> +
> +	printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode);
> +
> +	return mode;
> +}
> +
> +EXPORT_SYMBOL_GPL(ide_max_dma_mode);
> +

    I didn't quite like the array/loop approach but well, that's my taste (I'd
rather put the mode-from-mask evaluation to the function and call it thrice)...

> Index: b/drivers/ide/ide-lib.c
> ===================================================================
> --- a/drivers/ide/ide-lib.c
> +++ b/drivers/ide/ide-lib.c
> @@ -69,123 +69,34 @@ char *ide_xfer_verbose (u8 xfer_rate)
>  EXPORT_SYMBOL(ide_xfer_verbose);
>  
>  /**
> - *	ide_dma_speed	-	compute DMA speed
> - *	@drive: drive
> - *	@mode:	modes available
> - *
> - *	Checks the drive capabilities and returns the speed to use
> - *	for the DMA transfer.  Returns 0 if the drive is incapable
> - *	of DMA transfers.
> - */
> - 
> -u8 ide_dma_speed(ide_drive_t *drive, u8 mode)

[...]

> -EXPORT_SYMBOL(ide_dma_speed);

    Alas, my ide_dma_speed() fix is going to be oudated rather quickly... :-)

> Index: b/drivers/ide/pci/hpt366.c
> ===================================================================
> --- a/drivers/ide/pci/hpt366.c
> +++ b/drivers/ide/pci/hpt366.c
> @@ -513,43 +513,31 @@ static int check_in_drive_list(ide_drive
>  	return 0;
>  }
>  
> -static u8 hpt3xx_ratemask(ide_drive_t *drive)
> -{
> -	struct hpt_info *info	= pci_get_drvdata(HWIF(drive)->pci_dev);
> -	u8 mode			= info->max_mode;
> -
> -	if (!eighty_ninty_three(drive) && mode)
> -		mode = min(mode, (u8)1);
> -	return mode;
> -}
> -
>  /*
>   *	Note for the future; the SATA hpt37x we must set
>   *	either PIO or UDMA modes 0,4,5
>   */
> - 
> -static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed)
> +
> +static u8 hpt3xx_filter_udma_mask(ide_drive_t *drive)
>  {
>  	struct hpt_info *info	= pci_get_drvdata(HWIF(drive)->pci_dev);
>  	u8 chip_type		= info->chip_type;
> -	u8 mode			= hpt3xx_ratemask(drive);
> -
> -	if (drive->media != ide_disk)
> -		return min(speed, (u8)XFER_PIO_4);
> +	u8 mode			= info->max_mode;
> +	u8 mask;
>  
>  	switch (mode) {
>  		case 0x04:
> -			speed = min_t(u8, speed, XFER_UDMA_6);
> +			mask = 0x7f;
>  			break;
>  		case 0x03:
> -			speed = min_t(u8, speed, XFER_UDMA_5);
> +			mask = 0x3f;
>  			if (chip_type >= HPT374)
>  				break;
>  			if (!check_in_drive_list(drive, bad_ata100_5))
>  				goto check_bad_ata33;
>  			/* fall thru */
>  		case 0x02:
> -			speed = min_t(u8, speed, XFER_UDMA_4);
> +			mask = 0x1f;
>  
>  			/*
>  			 * CHECK ME, Does this need to be changed to HPT374 ??
> @@ -560,13 +548,13 @@ static u8 hpt3xx_ratefilter(ide_drive_t 
>  			    !check_in_drive_list(drive, bad_ata66_4))
>  				goto check_bad_ata33;
>  
> -			speed = min_t(u8, speed, XFER_UDMA_3);
> +			mask = 0x0f;
>  			if (HPT366_ALLOW_ATA66_3 &&
>  			    !check_in_drive_list(drive, bad_ata66_3))
>  				goto check_bad_ata33;
>  			/* fall thru */
>  		case 0x01:
> -			speed = min_t(u8, speed, XFER_UDMA_2);
> +			mask = 0x07;
>  
>  		check_bad_ata33:
>  			if (chip_type >= HPT370A)
> @@ -576,10 +564,10 @@ static u8 hpt3xx_ratefilter(ide_drive_t 
>  			/* fall thru */
>  		case 0x00:
>  		default:
> -			speed = min_t(u8, speed, XFER_MW_DMA_2);
> +			mask = 0x00;
>  			break;
>  	}
> -	return speed;
> +	return mask;
>  }

    Erm, I see.  This driver will need some redesign because 'struct hpt_info' 
was fitted for the old rate filtering model.  Looks like the 'max_mode' field 
should be replaced by 'ultra_mask' there...

>  static u32 get_speed_setting(u8 speed, struct hpt_info *info)
> @@ -607,12 +595,19 @@ static int hpt36x_tune_chipset(ide_drive
>  	ide_hwif_t *hwif	= HWIF(drive);
>  	struct pci_dev  *dev	= hwif->pci_dev;
>  	struct hpt_info	*info	= pci_get_drvdata(dev);
> -	u8  speed		= hpt3xx_ratefilter(drive, xferspeed);
> +	u8  speed		= ide_rate_filter(drive, xferspeed);
>  	u8  itr_addr		= drive->dn ? 0x44 : 0x40;
> -	u32 itr_mask		= speed < XFER_MW_DMA_0 ? 0x30070000 :
> -				 (speed < XFER_UDMA_0   ? 0xc0070000 : 0xc03800ff);
> -	u32 new_itr		= get_speed_setting(speed, info);
>  	u32 old_itr		= 0;
> +	u32 itr_mask, new_itr;
> +
> +	/* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
> +	if (drive->media != ide_disk)
> +		speed = min_t(u8, speed, XFER_PIO_4);
> +

    When I think about it, it seems quite stupid to set a PIO mode instead of 
a requested DMA one.  So, this is actually a questionable piece of code in 
this driver...

    Well, I must note the sorrow fact that both the IDE susbsytem as a whole 
doesn't keep track of PIO/DMA modes separately (having only current_mode) and 
the many drivers also fail to handle the timing registers shared by PIO/DMA 
modes correctly (well, it's actually also a hardware design issue :-).

> +	itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 :
> +		  (speed < XFER_UDMA_0   ? 0xc0070000 : 0xc03800ff);
> +
> +	new_itr = get_speed_setting(speed, info);

    Well, I liked this code where it was. But anyway, it's going to be 
replaced RSN...

> @@ -632,12 +627,19 @@ static int hpt37x_tune_chipset(ide_drive
>  	ide_hwif_t *hwif	= HWIF(drive);
>  	struct pci_dev  *dev	= hwif->pci_dev;
>  	struct hpt_info	*info	= pci_get_drvdata(dev);
> -	u8  speed		= hpt3xx_ratefilter(drive, xferspeed);
> +	u8  speed		= ide_rate_filter(drive, xferspeed);
>  	u8  itr_addr		= 0x40 + (drive->dn * 4);
> -	u32 itr_mask		= speed < XFER_MW_DMA_0 ? 0x303c0000 :
> -				 (speed < XFER_UDMA_0   ? 0xc03c0000 : 0xc1c001ff);
> -	u32 new_itr		= get_speed_setting(speed, info);
>  	u32 old_itr		= 0;
> +	u32 itr_mask, new_itr;
> +
> +	/* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
> +	if (drive->media != ide_disk)
> +		speed = min_t(u8, speed, XFER_PIO_4);
> +
> +	itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 :
> +		  (speed < XFER_UDMA_0   ? 0xc03c0000 : 0xc1c001ff);
> +
> +	new_itr = get_speed_setting(speed, info);

    Same comments here...

> Index: b/drivers/ide/pci/serverworks.c
> ===================================================================
> --- a/drivers/ide/pci/serverworks.c
> +++ b/drivers/ide/pci/serverworks.c
> @@ -65,16 +65,16 @@ static int check_in_drive_lists (ide_dri
>  	return 0;
>  }
>  
> -static u8 svwks_ratemask (ide_drive_t *drive)
> +static u8 svwks_filter_udma_mask(ide_drive_t *drive)
>  {
>  	struct pci_dev *dev     = HWIF(drive)->pci_dev;
> -	u8 mode = 0;
> +	u8 mask = 0;

    Hm, this looks like it needs rework...

>  	if (!svwks_revision)
>  		pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
>  
>  	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
> -		return 2;
> +		return 0x1f;
>  	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
>  		u32 reg = 0;
>  		if (isa_dev)
> @@ -86,25 +86,31 @@ static u8 svwks_ratemask (ide_drive_t *d
>  		if(drive->media == ide_disk)
>  			return 0;
>  		/* Check the OSB4 DMA33 enable bit */
> -		return ((reg & 0x00004000) == 0x00004000) ? 1 : 0;
> +		return ((reg & 0x00004000) == 0x00004000) ? 0x07 : 0;
>  	} else if (svwks_revision < SVWKS_CSB5_REVISION_NEW) {
> -		return 1;
> +		return 0x07;
>  	} else if (svwks_revision >= SVWKS_CSB5_REVISION_NEW) {
> -		u8 btr = 0;
> +		u8 btr = 0, mode;
>  		pci_read_config_byte(dev, 0x5A, &btr);
>  		mode = btr & 0x3;
> -		if (!eighty_ninty_three(drive))
> -			mode = min(mode, (u8)1);
> +
>  		/* If someone decides to do UDMA133 on CSB5 the same
>  		   issue will bite so be inclusive */
>  		if (mode > 2 && check_in_drive_lists(drive, svwks_bad_ata100))
>  			mode = 2;
> +
> +		switch(mode) {
> +		case 2:	 mask = 0x1f; break;
> +		case 1:	 mask = 0x07; break;
> +		default: mask = 0x00; break;
> +		}
>  	}
>  	if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
>  	     (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) &&
>  	    (!(PCI_FUNC(dev->devfn) & 1)))
> -		mode = 2;
> -	return mode;
> +		mask = 0x1f;
> +
> +	return mask;
>  }

    Hm, what was the problem with setting the proper masks based on PCI device 
ID in the init. code?
That'd have greatly simplified the filter...

> Index: b/drivers/ide/pci/siimage.c
> ===================================================================
> --- a/drivers/ide/pci/siimage.c
> +++ b/drivers/ide/pci/siimage.c
> @@ -116,45 +116,41 @@ static inline unsigned long siimage_seld
>  }
>  
>  /**
> - *	siimage_ratemask	-	Compute available modes
> - *	@drive: IDE drive
> + *	sil_filter_udma_mask	-	compute UDMA mask
> + *	@drive: IDE device
> + *
> + *	Compute the available UDMA speeds for the device on the interface.
>   *
> - *	Compute the available speeds for the devices on the interface.
>   *	For the CMD680 this depends on the clocking mode (scsc), for the
> - *	SI3312 SATA controller life is a bit simpler. Enforce UDMA33
> - *	as a limit if there is no 80pin cable present.
> + *	SI3112 SATA controller life is a bit simpler.
>   */
> - 
> -static byte siimage_ratemask (ide_drive_t *drive)
> +
> +static u8 sil_filter_udma_mask(ide_drive_t *drive)
>  {
> -	ide_hwif_t *hwif	= HWIF(drive);
> -	u8 mode	= 0, scsc = 0;
> +	ide_hwif_t *hwif = drive->hwif;
>  	unsigned long base = (unsigned long) hwif->hwif_data;
> +	u8 mask = 0, scsc = 0;
>  
>  	if (hwif->mmio)
>  		scsc = hwif->INB(base + 0x4A);
>  	else
>  		pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
>  
> -	if(is_sata(hwif))
> -	{
> -		if(strstr(drive->id->model, "Maxtor"))
> -			return 3;
> -		return 4;
> +	if (is_sata(hwif)) {
> +		mask = strstr(drive->id->model, "Maxtor") ? 0x3f : 0x7f;
> +		goto out;
>  	}
> -	
> +
>  	if ((scsc & 0x30) == 0x10)	/* 133 */
> -		mode = 4;
> +		mask = 0x7f;
>  	else if ((scsc & 0x30) == 0x20)	/* 2xPCI */
> -		mode = 4;
> +		mask = 0x7f;
>  	else if ((scsc & 0x30) == 0x00)	/* 100 */
> -		mode = 3;
> +		mask = 0x3f;
>  	else 	/* Disabled ? */
>  		BUG();

    Most probably this is doable at init. time also...

MBR, Sergei

PS: I understand that the intent wasn not to make this rewrite optimal but
do it quick and with least affect.  And I certainly may handle hpt366.c 
redesign... :-)


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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-01-22 18:46     ` Alan
@ 2007-01-22 20:28       ` Sergei Shtylyov
  2007-01-22 21:31         ` Alan
  2007-01-31 20:38       ` Sergei Shtylyov
  1 sibling, 1 reply; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-22 20:28 UTC (permalink / raw)
  To: Alan; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel

Hello.

Alan wrote:

>>    Ugh, I'm not seeing any *actual* support for MW/SW DMA in this driver... 

> Thats long been broken. Should be correct in the libata driver

    Here's a surprise for you. pata_cmd64x copied the SW/MW DMA setup code 
from the IDE driver.  No way it could be working.  You may check against the 
PC64x datasheets (if you have them -- if you don't I think I may share) and 
see for yourself -- it's abolutely idiotic.

> Alan

WBR, Sergei

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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-01-22 20:28       ` Sergei Shtylyov
@ 2007-01-22 21:31         ` Alan
  2007-01-22 22:39           ` Jeff Garzik
  2007-01-23 14:51           ` [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks Sergei Shtylyov
  0 siblings, 2 replies; 48+ messages in thread
From: Alan @ 2007-01-22 21:31 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel

> >>    Ugh, I'm not seeing any *actual* support for MW/SW DMA in this driver... 
> 
> > Thats long been broken. Should be correct in the libata driver
> 
>     Here's a surprise for you. pata_cmd64x copied the SW/MW DMA setup code 
> from the IDE driver.  No way it could be working.  You may check against the 
> PC64x datasheets (if you have them -- if you don't I think I may share) and 
> see for yourself -- it's abolutely idiotic.

Not a suprise to be honest. I fixed some of the ALi stuff when I did it
and I think that was pushed back into drivers/ide. The CMD64x hasn't had
much love really.

Wouldn't mind the older 64x (not 640) data sheets if they are sharable.


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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-01-22 21:31         ` Alan
@ 2007-01-22 22:39           ` Jeff Garzik
       [not found]             ` <45B6071C.90703@ru.mvista.com>
  2007-01-23 14:51           ` [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks Sergei Shtylyov
  1 sibling, 1 reply; 48+ messages in thread
From: Jeff Garzik @ 2007-01-22 22:39 UTC (permalink / raw)
  To: Alan; +Cc: Sergei Shtylyov, Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel

Alan wrote:
> Wouldn't mind the older 64x (not 640) data sheets if they are sharable.


If they are sharable, I would love to archive them at

	http://gkernel.sourceforge.net/specs/

Regards,

	Jeff



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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-01-22 21:31         ` Alan
  2007-01-22 22:39           ` Jeff Garzik
@ 2007-01-23 14:51           ` Sergei Shtylyov
  2007-01-25 15:40             ` Sergei Shtylyov
  1 sibling, 1 reply; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-23 14:51 UTC (permalink / raw)
  To: Alan; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel

Hello.

Alan wrote:
>>>>   Ugh, I'm not seeing any *actual* support for MW/SW DMA in this driver... 

>>>Thats long been broken. Should be correct in the libata driver

>>    Here's a surprise for you. pata_cmd64x copied the SW/MW DMA setup code 
>>from the IDE driver.  No way it could be working.  You may check against the 
>>PC64x datasheets (if you have them -- if you don't I think I may share) and 
>>see for yourself -- it's abolutely idiotic.

    I.e. MWDMA2 should be working due to the way the driver is written (it 
sets up PIO4 timings when auto-tuning DMA) but not the other modes since 
speedproc() method is brain-damaged in this part.

> Not a suprise to be honest. I fixed some of the ALi stuff when I did it
> and I think that was pushed back into drivers/ide. The CMD64x hasn't had
> much love really.

    Another buglet found by random glancing at this driver:

/**
  *      cmd648_dma_stop -       DMA stop callback
  *      @qc: Command in progress
  *
  *      DMA has completed.
  */

static void cmd648_bmdma_stop(struct ata_queued_cmd *qc)
{
         struct ata_port *ap = qc->ap;
         struct pci_dev *pdev = to_pci_dev(ap->host->dev);
         u8 dma_intr;
         int dma_reg = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
         int dma_mask = ap->port_no ? ARTTIM2 : CFR;

         ata_bmdma_stop(qc);

         pci_read_config_byte(pdev, dma_reg, &dma_intr);
         pci_write_config_byte(pdev, dma_reg, dma_intr | dma_mask);
}

    dma_reg and dma_mask initializers must have been swapped since ARTTIM2 and 
CFR are regster names.  So, the code reads/writes semi-random regs...

> Wouldn't mind the older 64x (not 640) data sheets if they are sharable.

    Sent what I had on this machine.  Will looks for newer revision of 
PCJ0646U2 spec elsewhere...

MBR, Sergei

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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-01-23 14:51           ` [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks Sergei Shtylyov
@ 2007-01-25 15:40             ` Sergei Shtylyov
  0 siblings, 0 replies; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-25 15:40 UTC (permalink / raw)
  To: Alan; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel

Hello.

Sergei Shtylyov wrote:

>> Not a suprise to be honest. I fixed some of the ALi stuff when I did it
>> and I think that was pushed back into drivers/ide. The CMD64x hasn't had
>> much love really.

>    Another buglet found by random glancing at this driver:

> /**
>  *      cmd648_dma_stop -       DMA stop callback
>  *      @qc: Command in progress
>  *
>  *      DMA has completed.
>  */

> static void cmd648_bmdma_stop(struct ata_queued_cmd *qc)
> {
>         struct ata_port *ap = qc->ap;
>         struct pci_dev *pdev = to_pci_dev(ap->host->dev);
>         u8 dma_intr;
>         int dma_reg = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
>         int dma_mask = ap->port_no ? ARTTIM2 : CFR;
> 
>         ata_bmdma_stop(qc);
> 
>         pci_read_config_byte(pdev, dma_reg, &dma_intr);
>         pci_write_config_byte(pdev, dma_reg, dma_intr | dma_mask);
> }

>    dma_reg and dma_mask initializers must have been swapped since 
> ARTTIM2 and CFR are regster names.  So, the code reads/writes 
> semi-random regs...

    BTW, on PCI0646U2 and later chips, the interrupt status (it's not really 
DMA interrupt status but a latched INTRQ signal not "coupled" with DMA logic, 
according to the datasheets) can be read from MRDMODE reg. which is accessible 
in I/O space at BMIDE base + 1 which is certainly faster.  That's what 
drivers/ide/cmd64x.c is doing in its test_dma_irq() method (however, it's 
doign this on PCI0643 and early revs of PCI0646 which don't have these bits).
The driver's dma_end() method is acting really strange: it checks if the cjip 
is PCI-648/9 and reads the PCI config space to clear those interrupt bits 
while these chips have them in I/O mapped MRDMODE; OTOH, it ignores these bits 
on earlier chips which have them in oonfig. space only (CFR/ARTTIM23 regs)... 
go figure.  I'm going to clean this up but don't heve the h/w handy... :-/

>> Wouldn't mind the older 64x (not 640) data sheets if they are sharable.

>    Sent what I had on this machine.  Will looks for newer revision of 
> PCJ0646U2 spec elsewhere...

    Sent rev. 1.3... Hopefully gkernel.sourceforge.net/specs/ will be updated.

MBR, Sergei

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

* Re: [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case
  2007-01-20 18:21                   ` Bartlomiej Zolnierkiewicz
  2007-01-20 18:41                     ` Sergei Shtylyov
@ 2007-01-25 17:03                     ` Sergei Shtylyov
  1 sibling, 0 replies; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-25 17:03 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:

>>>The other advantage of doing cleanups is that code becomes cleaner/simpler
>>>which matters a lot for this codebase, i.e. ide-dma-off-void.patch exposed
>>>(yet to be fixed) bug in set_using_dma() (->ide_dma_off_quietly always returns
>>>0 which is passed by ->ide_dma_check to set_using_dma() which incorrectly
>>>then calls ->ide_dma_on).

>>   Well, this seems a newly intruduced bug.

> The old code is so convulted that it is hard to see it w/o cleanup. :)

> ->ide_dma_check implementations often do

> 		return hwif->ide_dma_off_quietly(drive);

> so the return value of ide_dma_off_quietly() (which is always 0) is passed to

> 			if (HWIF(drive)->ide_dma_check(drive)) return -EIO;

> in ide.c:set_using_dma() -> as a result the next line is executed

> 			if (HWIF(drive)->ide_dma_on(drive)) return -EIO;

    So, the error seems to call hwif->ide_dma_on() after hwif->ide_dma_check() 
since hwif->ide_dma_check() must've already called that.

MBR, Sergei

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

* Updated SiI h/w docs (was Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks)
       [not found]               ` <45B761F8.1060505@ru.mvista.com>
@ 2007-01-25 22:20                 ` Jeff Garzik
  2007-01-26 13:14                   ` Sergei Shtylyov
  0 siblings, 1 reply; 48+ messages in thread
From: Jeff Garzik @ 2007-01-25 22:20 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-ide

Sergei Shtylyov wrote:
>    Now, the site seems to have 2 versions of the PCI-648/9 specs. :-)
> I looked into those in specs/sii and noted that PCI-648 spec was newer 
> than mine, but PCI-649 was older.
>    It's probably a good idea to put all the CMD/SiI files in the single 
> directory, so there's no dupes.
> 
>> PS: I certainly used to have a newer spec for PCI0646U2 but it's not 
>> at hand for some reason...
> 
>    Oops, this chip is named differently, without 0 -- that's why I 
> didn't notice the file locally. Sending rev 1.3 now...

(added linux-ide to CC and SiI folks to BCC)

All the docs are now at

	http://gkernel.sourceforge.net/specs/sii/

including the one you just sent.

	Jeff



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

* Re: Updated SiI h/w docs (was Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks)
  2007-01-25 22:20                 ` Updated SiI h/w docs (was Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks) Jeff Garzik
@ 2007-01-26 13:14                   ` Sergei Shtylyov
  0 siblings, 0 replies; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-26 13:14 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide

Hello.

Jeff Garzik wrote:

>>    Now, the site seems to have 2 versions of the PCI-648/9 specs. :-)
>> I looked into those in specs/sii and noted that PCI-648 spec was newer 
>> than mine, but PCI-649 was older.
>>    It's probably a good idea to put all the CMD/SiI files in the 
>> single directory, so there's no dupes.

>>> PS: I certainly used to have a newer spec for PCI0646U2 but it's not 
>>> at hand for some reason...

>>    Oops, this chip is named differently, without 0 -- that's why I 
>> didn't notice the file locally. Sending rev 1.3 now...

> (added linux-ide to CC and SiI folks to BCC)

> All the docs are now at

>     http://gkernel.sourceforge.net/specs/sii/

> including the one you just sent.

    Well, the purpose of avoiding dupes still not achieved. :-)
    Though maybe having several revisions of one spec is worth it...

     Jeff

MBR, Sergei

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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-01-22 18:46     ` Alan
  2007-01-22 20:28       ` Sergei Shtylyov
@ 2007-01-31 20:38       ` Sergei Shtylyov
  2007-01-31 23:24         ` Alan
  1 sibling, 1 reply; 48+ messages in thread
From: Sergei Shtylyov @ 2007-01-31 20:38 UTC (permalink / raw)
  To: Alan; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel

Hello.

Alan wrote:

>>    Ugh, I'm not seeing any *actual* support for MW/SW DMA in this driver... 

> Thats long been broken. Should be correct in the libata driver

    I've looked thru the specs and it seemed to me that ULi hardware is much 
broken PIO wise: their max active time is 8 cycles even on taskfile access 
which gives 240 ns while standard requeires 290 ns for modes 0 thru 2...

    I've also noted that the tuneproc() method in both cmd64x.c and alim15x3.c 
seems to misdo recovery calculation, taking address setup into account -- that 
should be slightly overclocking PIO modes 0/1 (ULi docs don't shed much light 
on how it should be calculated)... Well, this seems fixed in libata drivers.

> Alan

MBR, Sergei

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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-01-31 20:38       ` Sergei Shtylyov
@ 2007-01-31 23:24         ` Alan
  0 siblings, 0 replies; 48+ messages in thread
From: Alan @ 2007-01-31 23:24 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel

> should be slightly overclocking PIO modes 0/1 (ULi docs don't shed much light 
> on how it should be calculated)... Well, this seems fixed in libata drivers.

The libata code for tuning is based upon the BIOS programmers guide. That
seemed to be the best coverage of a minimal selection. It's also got a
big "confidential" stamp on it so I can't pass it on.

Alan

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

* Re: [PATCH 12/15] ide: make ide_hwif_t.ide_dma_host_on void
       [not found]     ` <58cb370e0702021128g15cac87ar507c20e78ded9464@mail.gmail.com>
@ 2007-02-02 21:16       ` Bartlomiej Zolnierkiewicz
  0 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-02-02 21:16 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-ide, linux-kernel


Sergei Shtylyov wrote:
> 
> Hello again. :-)
> 
> Bartlomiej Zolnierkiewicz wrote:
> 
>> [PATCH] ide: make ide_hwif_t.ide_dma_host_on void
> 
>> * since ide_hwif_t.ide_dma_host_on is called either when drive->using_dma == 1
>>   or when return value is discarded make it void, also drop "ide_" prefix
>> * make __ide_dma_host_on() void and drop "__" prefix
> 
>    Below are some nits which also apply to the previous patch...
> 
>> Index: b/drivers/ide/pci/atiixp.c
>> ===================================================================
>> --- a/drivers/ide/pci/atiixp.c
>> +++ b/drivers/ide/pci/atiixp.c
>> @@ -101,7 +101,7 @@ static u8 atiixp_dma_2_pio(u8 xfer_rate)
>>       }
>>  }
>>
>> -static int atiixp_ide_dma_host_on(ide_drive_t *drive)
>> +static void atiixp_ide_dma_host_on(ide_drive_t *drive)
>>  {
> 
>    Would seem logical to get rid of ide_ in this function's name also...

fixed in v2 version of the patch, thanks

>>       struct pci_dev *dev = drive->hwif->pci_dev;
>>       unsigned long flags;
> [...]
>> Index: b/drivers/ide/pci/sgiioc4.c
>> ===================================================================
>> --- a/drivers/ide/pci/sgiioc4.c
>> +++ b/drivers/ide/pci/sgiioc4.c
> [...]
>> @@ -307,13 +307,8 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * d
>>       return sgiioc4_checkirq(HWIF(drive));
>>  }
>>
>> -static int
>> -sgiioc4_ide_dma_host_on(ide_drive_t * drive)
>> +static void sgiioc4_ide_dma_host_on(ide_drive_t * drive)
> 
>    Same comment here...

ditto

I also fixed the previous patch.

>>  {
>> -     if (drive->using_dma)
>> -             return 0;
>> -
>> -     return 1;
>>  }
>>
>>  static void sgiioc4_ide_dma_host_off(ide_drive_t * drive)
>> @@ -610,7 +605,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
>>       hwif->ide_dma_on = &sgiioc4_ide_dma_on;
>>       hwif->dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
>>       hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
>> -     hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
>> +     hwif->dma_host_on = &sgiioc4_ide_dma_host_on;
>>       hwif->dma_host_off = &sgiioc4_ide_dma_host_off;
>>       hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
>>       hwif->ide_dma_timeout = &__ide_dma_timeout;
> 
>    Unrelated note: not sure why this default value needs explicit
> assignemnt...

SGIIOC4 is not PCI IDE BMDMA compatible - it uses its own SG list
format which supports 64-bit addresses.  Thus sgiioc4 driver doesn't use
the default IDE PCI initialization code [ ide_setup_pci_device[s]() ].

The default values are only assigned when using ide_setup_pci_device[s]():

ide_setup_pci_device[s]()
	do_ide_setup_pci_device()
		ide_pci_setup_ports()
			->init_setup_dma() [ or ide_hwif_setup_dma() ]
				->init_dma [ or ide_setup_dma() ]

Thanks,
Bart


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

* Re: [PATCH 11/15] ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void
       [not found]     ` <58cb370e0702021206h205ff983r88fb4bdbea42ed9f@mail.gmail.com>
@ 2007-02-02 22:39       ` Bartlomiej Zolnierkiewicz
  0 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-02-02 22:39 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-ide, linux-kernel


Sergei Shtylyov wrote:
> 
> Hello again. :-)
> 
> Bartlomiej Zolnierkiewicz wrote:
> 
>> [PATCH] ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void
> 
>    Below are my nits on the patch itself, and the code it changes.
> 
>> Index: b/drivers/ide/pci/atiixp.c
>> ===================================================================
>> --- a/drivers/ide/pci/atiixp.c
>> +++ b/drivers/ide/pci/atiixp.c
>> @@ -121,7 +121,7 @@ static int atiixp_ide_dma_host_on(ide_dr
>>       return __ide_dma_host_on(drive);
>>  }
>>
>> -static int atiixp_ide_dma_host_off(ide_drive_t *drive)
>> +static void atiixp_ide_dma_host_off(ide_drive_t *drive)
>>  {
>>       struct pci_dev *dev = drive->hwif->pci_dev;
>>       unsigned long flags;
> [...]
>> @@ -306,7 +306,7 @@ static void __devinit init_hwif_atiixp(i
>>               hwif->udma_four = 0;
>>
>>       hwif->ide_dma_host_on = &atiixp_ide_dma_host_on;
>> -     hwif->ide_dma_host_off = &atiixp_ide_dma_host_off;
>> +     hwif->dma_host_off = &atiixp_ide_dma_host_off;
>>       hwif->ide_dma_check = &atiixp_dma_check;
>>       if (!noautodma)
>>               hwif->autodma = 1;
> 
>    Would seem logical to get rid of ide_ in the function's name also...

done

>> Index: b/drivers/ide/pci/sgiioc4.c
>> ===================================================================
>> --- a/drivers/ide/pci/sgiioc4.c
>> +++ b/drivers/ide/pci/sgiioc4.c
>> @@ -282,12 +282,11 @@ sgiioc4_ide_dma_on(ide_drive_t * drive)
>>       return HWIF(drive)->ide_dma_host_on(drive);
>>  }
>>
>> -static int
>> -sgiioc4_ide_dma_off_quietly(ide_drive_t * drive)
>> +static void sgiioc4_ide_dma_off_quietly(ide_drive_t *drive)
>>  {
>>       drive->using_dma = 0;
>>
>> -     return HWIF(drive)->ide_dma_host_off(drive);
>> +     drive->hwif->dma_host_off(drive);
>>  }
>>
>>  static int sgiioc4_ide_dma_check(ide_drive_t *drive)
>> @@ -317,12 +316,9 @@ sgiioc4_ide_dma_host_on(ide_drive_t * dr
>>       return 1;
>>  }
>>
>> -static int
>> -sgiioc4_ide_dma_host_off(ide_drive_t * drive)
>> +static void sgiioc4_ide_dma_host_off(ide_drive_t * drive)
>>  {
>>       sgiioc4_clearirq(drive);
>> -
>> -     return 0;
>>  }
>>
>>  static int
>> @@ -612,10 +608,10 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
>>       hwif->ide_dma_end = &sgiioc4_ide_dma_end;
>>       hwif->ide_dma_check = &sgiioc4_ide_dma_check;
>>       hwif->ide_dma_on = &sgiioc4_ide_dma_on;
>> -     hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
>> +     hwif->dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
>>       hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
>>       hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
>> -     hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
>> +     hwif->dma_host_off = &sgiioc4_ide_dma_host_off;
>>       hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
>>       hwif->ide_dma_timeout = &__ide_dma_timeout;
> 
>    The same here...

done

>> Index: b/drivers/ide/pci/sl82c105.c
>> ===================================================================
>> --- a/drivers/ide/pci/sl82c105.c
>> +++ b/drivers/ide/pci/sl82c105.c
>> @@ -261,26 +261,24 @@ static int sl82c105_ide_dma_on (ide_driv
>>
>>       if (config_for_dma(drive)) {
>>               config_for_pio(drive, 4, 0, 0);
> 
>   Ugh, this forces PIO4 on fallback... and dma_on() doesn't select any modes
> in any other driver but this one. :-/

>From looking at config_for_dma() it seems that it is a bug and it is safe to
remove config_for_pio() call (as your "[PATCH] sl82c105: DMA support fixes" does).

>> -             return HWIF(drive)->ide_dma_off_quietly(drive);
>> +             drive->hwif->dma_off_quietly(drive);
>> +             return 0;
>>       }
>>       printk(KERN_INFO "%s: DMA enabled\n", drive->name);
>>       return __ide_dma_on(drive);
>>  }
>>
>> -static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive)
>> +static void sl82c105_ide_dma_off_quietly(ide_drive_t *drive)
> 
>    Also worth renaming...

done

>>  {
>>       u8 speed = XFER_PIO_0;
>> -     int rc;
>> -
>> +
>>       DBG(("sl82c105_ide_dma_off_quietly(drive:%s)\n", drive->name));
>>
>> -     rc = __ide_dma_off_quietly(drive);
>> +     ide_dma_off_quietly(drive);
>>       if (drive->pio_speed)
> 
>    Should always be non-zero since explicitly initialized.

yes

>>               speed = drive->pio_speed - XFER_PIO_0;
>>       config_for_pio(drive, speed, 0, 1);
>>       drive->current_speed = drive->pio_speed;
> 
>    dma_off() shouldn't be changing current_speed IMHO.

yep and your "[PATCH] sl82c105: DMA support fixes" fixes it

Bart

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

* Re: [PATCH 14/15] ide: rework the code for selecting the best DMA transfer mode
       [not found]     ` <58cb370e0702021207o435f39cdsf3abb0d55829fc45@mail.gmail.com>
@ 2007-02-02 23:57       ` Bartlomiej Zolnierkiewicz
  0 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-02-02 23:57 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-ide, linux-kernel


Hi,

Sergei Shtylyov wrote:
> 
> Hello.
> 
> Bartlomiej Zolnierkiewicz wrote:
> 
>> [PATCH] ide: rework the code for selecting the best DMA transfer mode
> 
>    Here's another portion of comments...
> 
>> Depends on the "ide: fix UDMA/MWDMA/SWDMA masks" patch.
> 
>> * add ide_hwif_t.filter_udma_mask hook for filtering UDMA mask
> 
>    Erm, maybe a shorter method name like udma_filter would go with the others
> better.  But well, that's my taste. :-)

done

>>   (use it in alim15x3, hpt366, siimage and serverworks drivers)
>> * add ide_max_dma_mode() for finding best DMA mode for the device
>>   (loosely based on some older libata-core.c code)
>> * convert ide_dma_speed() users to use ide_max_dma_mode()
>> * make ide_rate_filter() take "ide_drive_t *drive" as an argument instead
>>   of "u8 mode" and teach it to how to use UDMA mask to do filtering
>> * use ide_rate_filter() in hpt366 driver
>> * remove no longer needed ide_dma_speed() and *_ratemask()
>> * unexport eighty_ninty_three()
> 
>> Index: b/drivers/ide/ide-dma.c
>> ===================================================================
>> --- a/drivers/ide/ide-dma.c
>> +++ b/drivers/ide/ide-dma.c
>> @@ -705,6 +705,80 @@ int ide_use_dma(ide_drive_t *drive)
>>
>>  EXPORT_SYMBOL_GPL(ide_use_dma);
>>
>> +static const u8 xfer_mode_bases[] = {
>> +     XFER_UDMA_0,
>> +     XFER_MW_DMA_0,
>> +     XFER_SW_DMA_0,
>> +};
>> +
>> +static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base)
>> +{
>> +     struct hd_driveid *id = drive->id;
>> +     ide_hwif_t *hwif = drive->hwif;
>> +     unsigned int mask = 0;
>> +
>> +     switch(base) {
>> +     case XFER_UDMA_0:
>> +             if ((id->field_valid & 4) == 0)
>> +                     break;
>> +
>> +             mask = id->dma_ultra & hwif->ultra_mask;
>> +
>> +             if (hwif->filter_udma_mask)
>> +                     mask &= hwif->filter_udma_mask(drive);
>> +
>> +             if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
>> +                     mask &= 0x07;
>> +             break;
>> +     case XFER_MW_DMA_0:
>> +             mask = id->dma_mword & hwif->mwdma_mask;
>> +             break;
>> +     case XFER_SW_DMA_0:
>> +             mask = id->dma_1word & hwif->swdma_mask;
>> +             break;
>> +     default:
>> +             BUG();
>> +             break;
>> +     }
>> +
>> +     return mask;
>> +}
>> +
>> +/**
>> + *   ide_max_dma_mode        -       compute DMA speed
>> + *   @drive: IDE device
>> + *
>> + *   Checks the drive capabilities and returns the speed to use
>> + *   for the DMA transfer.  Returns 0 if the drive is incapable
>> + *   of DMA transfers.
>> + */
>> +
>> +u8 ide_max_dma_mode(ide_drive_t *drive)
>> +{
>> +     ide_hwif_t *hwif = drive->hwif;
>> +     unsigned int mask;
>> +     int x, i;
>> +     u8 mode = 0;
>> +
>> +     if (drive->media != ide_disk && hwif->atapi_dma == 0)
>> +             return 0;
>> +
>> +     for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) {
>> +             mask = ide_get_mode_mask(drive, xfer_mode_bases[i]);
>> +             x = fls(mask) - 1;
>> +             if (x >= 0) {
>> +                     mode = xfer_mode_bases[i] + x;
>> +                     break;
>> +             }
>> +     }
>> +
>> +     printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode);
>> +
>> +     return mode;
>> +}
>> +
>> +EXPORT_SYMBOL_GPL(ide_max_dma_mode);
>> +
> 
>    I didn't quite like the array/loop approach but well, that's my taste (I'd
> rather put the mode-from-mask evaluation to the function and call it thrice)...

The mode-from-mask approach is indeed nicer.  If you send me a patch to
use the mode-from-mask evaluation I'll happily apply it. :)

However the array/loop approach is also definitively an improvement
over the current code.

>> Index: b/drivers/ide/ide-lib.c
>> ===================================================================
>> --- a/drivers/ide/ide-lib.c
>> +++ b/drivers/ide/ide-lib.c
>> @@ -69,123 +69,34 @@ char *ide_xfer_verbose (u8 xfer_rate)
>>  EXPORT_SYMBOL(ide_xfer_verbose);
>>
>>  /**
>> - *   ide_dma_speed   -       compute DMA speed
>> - *   @drive: drive
>> - *   @mode:  modes available
>> - *
>> - *   Checks the drive capabilities and returns the speed to use
>> - *   for the DMA transfer.  Returns 0 if the drive is incapable
>> - *   of DMA transfers.
>> - */
>> -
>> -u8 ide_dma_speed(ide_drive_t *drive, u8 mode)
> 
> [...]
> 
>> -EXPORT_SYMBOL(ide_dma_speed);
> 
>    Alas, my ide_dma_speed() fix is going to be oudated rather quickly... :-)

C'est la vie :)

>> Index: b/drivers/ide/pci/hpt366.c
>> ===================================================================
>> --- a/drivers/ide/pci/hpt366.c
>> +++ b/drivers/ide/pci/hpt366.c
>> @@ -513,43 +513,31 @@ static int check_in_drive_list(ide_drive
>>       return 0;
>>  }
>>
>> -static u8 hpt3xx_ratemask(ide_drive_t *drive)
>> -{
>> -     struct hpt_info *info   = pci_get_drvdata(HWIF(drive)->pci_dev);
>> -     u8 mode                 = info->max_mode;
>> -
>> -     if (!eighty_ninty_three(drive) && mode)
>> -             mode = min(mode, (u8)1);
>> -     return mode;
>> -}
>> -
>>  /*
>>   *   Note for the future; the SATA hpt37x we must set
>>   *   either PIO or UDMA modes 0,4,5
>>   */
>> -
>> -static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed)
>> +
>> +static u8 hpt3xx_filter_udma_mask(ide_drive_t *drive)
>>  {
>>       struct hpt_info *info   = pci_get_drvdata(HWIF(drive)->pci_dev);
>>       u8 chip_type            = info->chip_type;
>> -     u8 mode                 = hpt3xx_ratemask(drive);
>> -
>> -     if (drive->media != ide_disk)
>> -             return min(speed, (u8)XFER_PIO_4);
>> +     u8 mode                 = info->max_mode;
>> +     u8 mask;
>>
>>       switch (mode) {
>>               case 0x04:
>> -                     speed = min_t(u8, speed, XFER_UDMA_6);
>> +                     mask = 0x7f;
>>                       break;
>>               case 0x03:
>> -                     speed = min_t(u8, speed, XFER_UDMA_5);
>> +                     mask = 0x3f;
>>                       if (chip_type >= HPT374)
>>                               break;
>>                       if (!check_in_drive_list(drive, bad_ata100_5))
>>                               goto check_bad_ata33;
>>                       /* fall thru */
>>               case 0x02:
>> -                     speed = min_t(u8, speed, XFER_UDMA_4);
>> +                     mask = 0x1f;
>>
>>                       /*
>>                        * CHECK ME, Does this need to be changed to HPT374 ??
>> @@ -560,13 +548,13 @@ static u8 hpt3xx_ratefilter(ide_drive_t
>>                           !check_in_drive_list(drive, bad_ata66_4))
>>                               goto check_bad_ata33;
>>
>> -                     speed = min_t(u8, speed, XFER_UDMA_3);
>> +                     mask = 0x0f;
>>                       if (HPT366_ALLOW_ATA66_3 &&
>>                           !check_in_drive_list(drive, bad_ata66_3))
>>                               goto check_bad_ata33;
>>                       /* fall thru */
>>               case 0x01:
>> -                     speed = min_t(u8, speed, XFER_UDMA_2);
>> +                     mask = 0x07;
>>
>>               check_bad_ata33:
>>                       if (chip_type >= HPT370A)
>> @@ -576,10 +564,10 @@ static u8 hpt3xx_ratefilter(ide_drive_t
>>                       /* fall thru */
>>               case 0x00:
>>               default:
>> -                     speed = min_t(u8, speed, XFER_MW_DMA_2);
>> +                     mask = 0x00;
>>                       break;
>>       }
>> -     return speed;
>> +     return mask;
>>  }
> 
>    Erm, I see.  This driver will need some redesign because 'struct hpt_info'
> was fitted for the old rate filtering model.  Looks like the 'max_mode' field
> should be replaced by 'ultra_mask' there...

yes...

>>  static u32 get_speed_setting(u8 speed, struct hpt_info *info)
>> @@ -607,12 +595,19 @@ static int hpt36x_tune_chipset(ide_drive
>>       ide_hwif_t *hwif        = HWIF(drive);
>>       struct pci_dev  *dev    = hwif->pci_dev;
>>       struct hpt_info *info   = pci_get_drvdata(dev);
>> -     u8  speed               = hpt3xx_ratefilter(drive, xferspeed);
>> +     u8  speed               = ide_rate_filter(drive, xferspeed);
>>       u8  itr_addr            = drive->dn ? 0x44 : 0x40;
>> -     u32 itr_mask            = speed < XFER_MW_DMA_0 ? 0x30070000 :
>> -                              (speed < XFER_UDMA_0   ? 0xc0070000 : 0xc03800ff);
>> -     u32 new_itr             = get_speed_setting(speed, info);
>>       u32 old_itr             = 0;
>> +     u32 itr_mask, new_itr;
>> +
>> +     /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
>> +     if (drive->media != ide_disk)
>> +             speed = min_t(u8, speed, XFER_PIO_4);
>> +
> 
>    When I think about it, it seems quite stupid to set a PIO mode instead of
> a requested DMA one.  So, this is actually a questionable piece of code in
> this driver...

This can safely vanish when core code gets fixed to correctly check device+host
supported PIO/DMA modes before calling ->tuneproc/->speedproc for user space
originated code change requests.

As for now IMHO it is the best to just leave it alone...

>    Well, I must note the sorrow fact that both the IDE susbsytem as a whole
> doesn't keep track of PIO/DMA modes separately (having only current_mode) and
> the many drivers also fail to handle the timing registers shared by PIO/DMA
> modes correctly (well, it's actually also a hardware design issue :-).

Actually, I have an unfinished patch to fix it but it depends on
many other unfinished patches... *sigh*...

>> +     itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 :
>> +               (speed < XFER_UDMA_0   ? 0xc0070000 : 0xc03800ff);
>> +
>> +     new_itr = get_speed_setting(speed, info);
> 
>    Well, I liked this code where it was. But anyway, it's going to be
> replaced RSN...
> 
>> @@ -632,12 +627,19 @@ static int hpt37x_tune_chipset(ide_drive
>>       ide_hwif_t *hwif        = HWIF(drive);
>>       struct pci_dev  *dev    = hwif->pci_dev;
>>       struct hpt_info *info   = pci_get_drvdata(dev);
>> -     u8  speed               = hpt3xx_ratefilter(drive, xferspeed);
>> +     u8  speed               = ide_rate_filter(drive, xferspeed);
>>       u8  itr_addr            = 0x40 + (drive->dn * 4);
>> -     u32 itr_mask            = speed < XFER_MW_DMA_0 ? 0x303c0000 :
>> -                              (speed < XFER_UDMA_0   ? 0xc03c0000 : 0xc1c001ff);
>> -     u32 new_itr             = get_speed_setting(speed, info);
>>       u32 old_itr             = 0;
>> +     u32 itr_mask, new_itr;
>> +
>> +     /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
>> +     if (drive->media != ide_disk)
>> +             speed = min_t(u8, speed, XFER_PIO_4);
>> +
>> +     itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 :
>> +               (speed < XFER_UDMA_0   ? 0xc03c0000 : 0xc1c001ff);
>> +
>> +     new_itr = get_speed_setting(speed, info);
> 
>    Same comments here...
> 
>> Index: b/drivers/ide/pci/serverworks.c
>> ===================================================================
>> --- a/drivers/ide/pci/serverworks.c
>> +++ b/drivers/ide/pci/serverworks.c
>> @@ -65,16 +65,16 @@ static int check_in_drive_lists (ide_dri
>>       return 0;
>>  }
>>
>> -static u8 svwks_ratemask (ide_drive_t *drive)
>> +static u8 svwks_filter_udma_mask(ide_drive_t *drive)
>>  {
>>       struct pci_dev *dev     = HWIF(drive)->pci_dev;
>> -     u8 mode = 0;
>> +     u8 mask = 0;
> 
>    Hm, this looks like it needs rework...

...some time later. 8)

>>       if (!svwks_revision)
>>               pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
>>
>>       if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
>> -             return 2;
>> +             return 0x1f;
>>       if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
>>               u32 reg = 0;
>>               if (isa_dev)
>> @@ -86,25 +86,31 @@ static u8 svwks_ratemask (ide_drive_t *d
>>               if(drive->media == ide_disk)
>>                       return 0;
>>               /* Check the OSB4 DMA33 enable bit */
>> -             return ((reg & 0x00004000) == 0x00004000) ? 1 : 0;
>> +             return ((reg & 0x00004000) == 0x00004000) ? 0x07 : 0;
>>       } else if (svwks_revision < SVWKS_CSB5_REVISION_NEW) {
>> -             return 1;
>> +             return 0x07;
>>       } else if (svwks_revision >= SVWKS_CSB5_REVISION_NEW) {
>> -             u8 btr = 0;
>> +             u8 btr = 0, mode;
>>               pci_read_config_byte(dev, 0x5A, &btr);
>>               mode = btr & 0x3;
>> -             if (!eighty_ninty_three(drive))
>> -                     mode = min(mode, (u8)1);
>> +
>>               /* If someone decides to do UDMA133 on CSB5 the same
>>                  issue will bite so be inclusive */
>>               if (mode > 2 && check_in_drive_lists(drive, svwks_bad_ata100))
>>                       mode = 2;
>> +
>> +             switch(mode) {
>> +             case 2:  mask = 0x1f; break;
>> +             case 1:  mask = 0x07; break;
>> +             default: mask = 0x00; break;
>> +             }
>>       }
>>       if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
>>            (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) &&
>>           (!(PCI_FUNC(dev->devfn) & 1)))
>> -             mode = 2;
>> -     return mode;
>> +             mask = 0x1f;
>> +
>> +     return mask;
>>  }
> 
>    Hm, what was the problem with setting the proper masks based on PCI
> device ID in the init. code?
> That'd have greatly simplified the filter...

I don't see a problem with doing it during initialization but simplifying
this code wasn't the goal of this patch and can be done in the future.

>> Index: b/drivers/ide/pci/siimage.c
>> ===================================================================
>> --- a/drivers/ide/pci/siimage.c
>> +++ b/drivers/ide/pci/siimage.c
>> @@ -116,45 +116,41 @@ static inline unsigned long siimage_seld
>>  }
>>
>>  /**
>> - *   siimage_ratemask        -       Compute available modes
>> - *   @drive: IDE drive
>> + *   sil_filter_udma_mask    -       compute UDMA mask
>> + *   @drive: IDE device
>> + *
>> + *   Compute the available UDMA speeds for the device on the interface.
>>   *
>> - *   Compute the available speeds for the devices on the interface.
>>   *   For the CMD680 this depends on the clocking mode (scsc), for the
>> - *   SI3312 SATA controller life is a bit simpler. Enforce UDMA33
>> - *   as a limit if there is no 80pin cable present.
>> + *   SI3112 SATA controller life is a bit simpler.
>>   */
>> -
>> -static byte siimage_ratemask (ide_drive_t *drive)
>> +
>> +static u8 sil_filter_udma_mask(ide_drive_t *drive)
>>  {
>> -     ide_hwif_t *hwif        = HWIF(drive);
>> -     u8 mode = 0, scsc = 0;
>> +     ide_hwif_t *hwif = drive->hwif;
>>       unsigned long base = (unsigned long) hwif->hwif_data;
>> +     u8 mask = 0, scsc = 0;
>>
>>       if (hwif->mmio)
>>               scsc = hwif->INB(base + 0x4A);
>>       else
>>               pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
>>
>> -     if(is_sata(hwif))
>> -     {
>> -             if(strstr(drive->id->model, "Maxtor"))
>> -                     return 3;
>> -             return 4;
>> +     if (is_sata(hwif)) {
>> +             mask = strstr(drive->id->model, "Maxtor") ? 0x3f : 0x7f;
>> +             goto out;
>>       }
>> -
>> +
>>       if ((scsc & 0x30) == 0x10)      /* 133 */
>> -             mode = 4;
>> +             mask = 0x7f;
>>       else if ((scsc & 0x30) == 0x20) /* 2xPCI */
>> -             mode = 4;
>> +             mask = 0x7f;
>>       else if ((scsc & 0x30) == 0x00) /* 100 */
>> -             mode = 3;
>> +             mask = 0x3f;
>>       else    /* Disabled ? */
>>               BUG();
> 
>    Most probably this is doable at init. time also...

ditto

patches welcomed (I added this to the IDE tree TODO)

> MBR, Sergei
> 
> PS: I understand that the intent wasn not to make this rewrite optimal but
> do it quick and with least affect.  And I certainly may handle hpt366.c
> redesign... :-)

Please do.

Thanks,
Bart

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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
       [not found]     ` <58cb370e0702021606v4efa6143lf060e6aab9782c35@mail.gmail.com>
@ 2007-02-03  0:39       ` Bartlomiej Zolnierkiewicz
  2007-02-03 16:30         ` Sergei Shtylyov
  0 siblings, 1 reply; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-02-03  0:39 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-ide, linux-kernel


Hi,

Sergei Shtylyov wrote:
> 
> Hello.
> 
> Bartlomiej Zolnierkiewicz wrote:
> 
>> [PATCH] ide: fix UDMA/MWDMA/SWDMA masks
> 
>> * use 0x00 instead of 0x80 to disable ->{ultra,mwdma,swdma}_mask
>> * add udma_mask field to ide_pci_device_t and use it to initialize
>>   ->ultra_mask in aec62xx, pdc202xx_new and pdc202xx_old drivers
>> * fix UDMA masks to match with chipset specific *_ratemask()
>>   (alim15x3, hpt366, serverworks and siimage drivers need UDMA mask
>>    filtering method - done in the next patch)
> 
>    More nit picking (-:
> 
>> Index: b/drivers/ide/pci/cmd64x.c
>> ===================================================================
>> --- a/drivers/ide/pci/cmd64x.c
>> +++ b/drivers/ide/pci/cmd64x.c
>> @@ -695,9 +695,10 @@ static void __devinit init_hwif_cmd64x(i
>>       hwif->swdma_mask = 0x07;
>>
>>       if (dev->device == PCI_DEVICE_ID_CMD_643)
>> -             hwif->ultra_mask = 0x80;
>> +             hwif->ultra_mask = 0x00;
>>       if (dev->device == PCI_DEVICE_ID_CMD_646)
>> -             hwif->ultra_mask = (class_rev > 0x04) ? 0x07 : 0x80;
>> +             hwif->ultra_mask =
>> +                     (class_rev == 0x05 || class_rev == 0x07) ? 0x07 : 0x00;
>>       if (dev->device == PCI_DEVICE_ID_CMD_648)
>>               hwif->ultra_mask = 0x1f;
> 
>    Hm, well, this doesn't look consistent with the changes in other drivers.
> This driver asks for explicit hwif->cds->ultra_mask initializers, IMO...
>    You'd only have to check for PCI-646 revisions < 5 then...

reworked

>> Index: b/drivers/ide/pci/piix.c
>> ===================================================================
>> --- a/drivers/ide/pci/piix.c
>> +++ b/drivers/ide/pci/piix.c
>> @@ -493,7 +493,7 @@ static void __devinit init_hwif_piix(ide
>>               case PCI_DEVICE_ID_INTEL_82371FB_0:
>>               case PCI_DEVICE_ID_INTEL_82371FB_1:
>>               case PCI_DEVICE_ID_INTEL_82371SB_1:
>> -                     hwif->ultra_mask = 0x80;
>> +                     hwif->ultra_mask = 0x00;
>>                       break;
>>               case PCI_DEVICE_ID_INTEL_82371AB:
>>               case PCI_DEVICE_ID_INTEL_82443MX_1:
>> @@ -501,6 +501,10 @@ static void __devinit init_hwif_piix(ide
>>               case PCI_DEVICE_ID_INTEL_82801AB_1:
>>                       hwif->ultra_mask = 0x07;
>>                       break;
>> +             case PCI_DEVICE_ID_INTEL_82801AA_1:
>> +             case PCI_DEVICE_ID_INTEL_82372FB_1:
>> +                     hwif->ultra_mask = 0x1f;
>> +                     break;
> 
>    Alas, I'm afraid this part is wrong!
>    At least, the cable detection should work for 82801AA the same way as for
> the 82801Bx and newer chips, if Intel's datasheet is to be trusted... I think
> we should fall thru here.

yes (extra "break:" shouldn't be there), fixed

>>               default:
>>                       if (!hwif->udma_four)
>>                               hwif->udma_four = piix_cable_detect(hwif);
> 
>    This one also certainly asks for explicit hwif->cds->ultra_mask
> initializers... Thus almost all of this switch statement could go away...
	
Alas doing it now would make the nice DECLARE_PIIX_DEV() macro go away
(=> a lot of duplicated code)... could be done in the future...

Thanks,
Bart


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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
       [not found]     ` <58cb370e0702021606m4eb6f682xfa4bf769d398cf9@mail.gmail.com>
@ 2007-02-03  0:50       ` Bartlomiej Zolnierkiewicz
  0 siblings, 0 replies; 48+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2007-02-03  0:50 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-ide, linux-kernel


Sergei Shtylyov wrote:
> 
> Hello.
> 
> Bartlomiej Zolnierkiewicz wrote:
> 
>> [PATCH] ide: fix UDMA/MWDMA/SWDMA masks
> 
>> * use 0x00 instead of 0x80 to disable ->{ultra,mwdma,swdma}_mask
>> * add udma_mask field to ide_pci_device_t and use it to initialize
>>   ->ultra_mask in aec62xx, pdc202xx_new and pdc202xx_old drivers
>> * fix UDMA masks to match with chipset specific *_ratemask()
>>   (alim15x3, hpt366, serverworks and siimage drivers need UDMA mask
>>    filtering method - done in the next patch)
> 
>    More issues with aec62xx.c driver, found after looking at the next
> patch...
> 
>> Index: b/drivers/ide/pci/aec62xx.c
>> ===================================================================
>> --- a/drivers/ide/pci/aec62xx.c
>> +++ b/drivers/ide/pci/aec62xx.c
>> @@ -270,11 +270,13 @@ static unsigned int __devinit init_chips
>>
>>  static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
>>  {
>> +     struct pci_dev *dev = hwif->pci_dev;
>> +
>>       hwif->autodma = 0;
>>       hwif->tuneproc = &aec62xx_tune_drive;
>>       hwif->speedproc = &aec62xx_tune_chipset;
>>
>> -     if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
>> +     if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
>>               hwif->serialized = hwif->channel;
>>
>>       if (hwif->mate)
>> @@ -286,7 +288,16 @@ static void __devinit init_hwif_aec62xx(
>>               return;
>>       }
>>
>> -     hwif->ultra_mask = 0x7f;
>> +     hwif->ultra_mask = hwif->cds->udma_mask;
>> +
>> +     /* atp865 and atp865r */
>> +     if (hwif->ultra_mask == 0x3f) {
>> +             unsigned long io = pci_resource_start(dev, 4);
>> +
>> +             if (inb(io) & 0x10)
>> +                     hwif->ultra_mask = 0x7f; /* udma0-6 */
>> +     }
>> +
> 
>    Looks like another intruduced buglet: you're reading DMA command, but
> aec62xx_ratemask() was reading DMA status originally for this bit.

Doh, fixed.  Thanks for catching this.

>>       hwif->mwdma_mask = 0x07;
>>       hwif->swdma_mask = 0x07;
> 
>    Hm, caught another nit: this driver doesn't actually support single-word
> DMA modes... :-)

added to TODO

>> Index: b/drivers/ide/pci/alim15x3.c
>> ===================================================================
>> --- a/drivers/ide/pci/alim15x3.c
>> +++ b/drivers/ide/pci/alim15x3.c
>> @@ -765,8 +765,17 @@ static void __devinit init_hwif_common_a
>>
>>       hwif->atapi_dma = 1;
>>
>> -     if (m5229_revision > 0x20)
>> -             hwif->ultra_mask = 0x7f;
>> +     if (m5229_revision <= 0x20)
>> +             hwif->ultra_mask = 0x00; /* no udma */
>> +     else if (m5229_revision < 0xC2)
>> +             hwif->ultra_mask = 0x07; /* udma0-2 */
>> +     else if (m5229_revision == 0xC2 || m5229_revision == 0xC3)
>> +             hwif->ultra_mask = 0x1f; /* udma0-4 */
>> +     else if (m5229_revision == 0xC4)
>> +             hwif->ultra_mask = 0x3f; /* udma0-5 */
>> +     else
>> +             hwif->ultra_mask = 0x7f; /* udma0-6 */
>> +
>>       hwif->mwdma_mask = 0x07;
>>       hwif->swdma_mask = 0x07;
> 
>    Ugh, I'm not seeing any *actual* support for MW/SW DMA in this driver...
> And PIO setting via speedproc() method is broken -- it passes to tuneproc()
> method mode number not biased by -XFER_PIO_0 beforehand.  Will cook up some
> patch, maybe... :-/

Please do, I added this to IDE TODO to not forget about the issue...

Thanks,
Bart

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

* Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
  2007-02-03  0:39       ` Bartlomiej Zolnierkiewicz
@ 2007-02-03 16:30         ` Sergei Shtylyov
  0 siblings, 0 replies; 48+ messages in thread
From: Sergei Shtylyov @ 2007-02-03 16:30 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:

>>>Index: b/drivers/ide/pci/cmd64x.c
>>>===================================================================
>>>--- a/drivers/ide/pci/cmd64x.c
>>>+++ b/drivers/ide/pci/cmd64x.c
>>>@@ -695,9 +695,10 @@ static void __devinit init_hwif_cmd64x(i
>>>      hwif->swdma_mask = 0x07;
>>>
>>>      if (dev->device == PCI_DEVICE_ID_CMD_643)
>>>-             hwif->ultra_mask = 0x80;
>>>+             hwif->ultra_mask = 0x00;
>>>      if (dev->device == PCI_DEVICE_ID_CMD_646)
>>>-             hwif->ultra_mask = (class_rev > 0x04) ? 0x07 : 0x80;
>>>+             hwif->ultra_mask =
>>>+                     (class_rev == 0x05 || class_rev == 0x07) ? 0x07 : 0x00;
>>>      if (dev->device == PCI_DEVICE_ID_CMD_648)
>>>              hwif->ultra_mask = 0x1f;

>>   Hm, well, this doesn't look consistent with the changes in other drivers.
>>This driver asks for explicit hwif->cds->ultra_mask initializers, IMO...
>>   You'd only have to check for PCI-646 revisions < 5 then...

> reworked

    Thanks. :-)

>>>Index: b/drivers/ide/pci/piix.c
>>>===================================================================
>>>--- a/drivers/ide/pci/piix.c
>>>+++ b/drivers/ide/pci/piix.c
>>>              default:
>>>                      if (!hwif->udma_four)
>>>                              hwif->udma_four = piix_cable_detect(hwif);

>>   This one also certainly asks for explicit hwif->cds->ultra_mask
>>initializers... Thus almost all of this switch statement could go away...
  	
> Alas doing it now would make the nice DECLARE_PIIX_DEV() macro go away

    Why? Could add another argument to that macro...

> (=> a lot of duplicated code)... could be done in the future...

    Yes, of course.

> Thanks,
> Bart

MBR, Sergei

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

* Re: [PATCH 12/15] ide: make ide_hwif_t.ide_dma_host_on void
  2007-01-19  0:32 ` [PATCH 12/15] ide: make ide_hwif_t.ide_dma_host_on void Bartlomiej Zolnierkiewicz
  2007-01-20 20:46   ` Sergei Shtylyov
@ 2007-03-26 17:19   ` Sergei Shtylyov
  2007-04-20 20:36     ` Sergei Shtylyov
  1 sibling, 1 reply; 48+ messages in thread
From: Sergei Shtylyov @ 2007-03-26 17:19 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:
> [PATCH] ide: make ide_hwif_t.ide_dma_host_on void

> * since ide_hwif_t.ide_dma_host_on is called either when drive->using_dma == 1
>   or when return value is discarded make it void, also drop "ide_" prefix
> * make __ide_dma_host_on() void and drop "__" prefix

    BTW, it would also make sense to make hwif->ide_dma_timeout() and 
hwif->ide_dma_lostirq void too (and possibly drop the ide_ prefix). Their 
results are *explicitly* ignored.

MBR, Sergei

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

* Re: [PATCH 12/15] ide: make ide_hwif_t.ide_dma_host_on void
  2007-03-26 17:19   ` Sergei Shtylyov
@ 2007-04-20 20:36     ` Sergei Shtylyov
  0 siblings, 0 replies; 48+ messages in thread
From: Sergei Shtylyov @ 2007-04-20 20:36 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello, once I wrote:

>> [PATCH] ide: make ide_hwif_t.ide_dma_host_on void
 
>> * since ide_hwif_t.ide_dma_host_on is called either when 
>> drive->using_dma == 1
>>   or when return value is discarded make it void, also drop "ide_" prefix
>> * make __ide_dma_host_on() void and drop "__" prefix

>    BTW, it would also make sense to make hwif->ide_dma_timeout() and 
> hwif->ide_dma_lostirq void too (and possibly drop the ide_ prefix). 
> Their results are *explicitly* ignored.

   I've started preparing the patches and found out that aec62xx has completely bogus ide_dma_timeout() -- the same as ide_dma_lostirq() and it doesn't even call __ide_dma_timeout()... :-/
   Don't know whether to deal with this in a separate patch...

MBR, Sergei

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

end of thread, other threads:[~2007-04-20 20:35 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-19  0:30 [PATCH 0/15] IDE quilt tree updated Bartlomiej Zolnierkiewicz
2007-01-19  0:31 ` [PATCH 1/15] ACPI support for IDE devices Bartlomiej Zolnierkiewicz
2007-01-19  0:31 ` [PATCH 2/15] via82cxxx/pata_via: correct PCI_DEVICE_ID_VIA_SATA_EIDE ID and add support for CX700 and 8237S Bartlomiej Zolnierkiewicz
2007-01-19  0:31 ` [PATCH 3/15] it8213: fix build and ->ultra_mask Bartlomiej Zolnierkiewicz
2007-01-19  0:31 ` [PATCH 4/15] ide: convert ide_hwif_t.mmio into flag Bartlomiej Zolnierkiewicz
2007-01-19  0:31 ` [PATCH 5/15] hpt34x: hpt34x_tune_chipset() (->speedproc) fix Bartlomiej Zolnierkiewicz
2007-01-19  0:31 ` [PATCH 6/15] atiixp/jmicron/triflex: fix PIO fallback Bartlomiej Zolnierkiewicz
2007-01-19  0:31 ` [PATCH 7/15] piix: cleanup Bartlomiej Zolnierkiewicz
2007-01-19  0:31 ` [PATCH 8/15] ide: disable DMA in ->ide_dma_check for "no IORDY" case Bartlomiej Zolnierkiewicz
2007-01-19 16:26   ` Sergei Shtylyov
     [not found]     ` <58cb370e0701191047h524434eobdb9d86ed614bc71@mail.gmail.com>
2007-01-19 19:11       ` Bartlomiej Zolnierkiewicz
2007-01-19 19:35         ` Sergei Shtylyov
     [not found]           ` <58cb370e0701191200i10119313i4aacae9c504a02e4@mail.gmail.com>
2007-01-19 21:43             ` Bartlomiej Zolnierkiewicz
2007-01-20 17:09               ` Sergei Shtylyov
     [not found]                 ` <58cb370e0701200947p578f4d74g1fee511ded6c9a77@mail.gmail.com>
2007-01-20 18:21                   ` Bartlomiej Zolnierkiewicz
2007-01-20 18:41                     ` Sergei Shtylyov
2007-01-25 17:03                     ` Sergei Shtylyov
2007-01-19  0:32 ` [PATCH 9/15] sgiioc4: fix sgiioc4_ide_dma_check() to enable/disable DMA properly Bartlomiej Zolnierkiewicz
2007-01-19  0:32 ` [PATCH 10/15] ide: add ide_set_dma() helper Bartlomiej Zolnierkiewicz
2007-01-20 20:22   ` Sergei Shtylyov
2007-01-19  0:32 ` [PATCH 11/15] ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void Bartlomiej Zolnierkiewicz
2007-01-20 20:56   ` Sergei Shtylyov
     [not found]     ` <58cb370e0702021206h205ff983r88fb4bdbea42ed9f@mail.gmail.com>
2007-02-02 22:39       ` Bartlomiej Zolnierkiewicz
2007-01-19  0:32 ` [PATCH 12/15] ide: make ide_hwif_t.ide_dma_host_on void Bartlomiej Zolnierkiewicz
2007-01-20 20:46   ` Sergei Shtylyov
     [not found]     ` <58cb370e0702021128g15cac87ar507c20e78ded9464@mail.gmail.com>
2007-02-02 21:16       ` Bartlomiej Zolnierkiewicz
2007-03-26 17:19   ` Sergei Shtylyov
2007-04-20 20:36     ` Sergei Shtylyov
2007-01-19  0:32 ` [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks Bartlomiej Zolnierkiewicz
2007-01-22 16:19   ` Sergei Shtylyov
     [not found]     ` <58cb370e0702021606v4efa6143lf060e6aab9782c35@mail.gmail.com>
2007-02-03  0:39       ` Bartlomiej Zolnierkiewicz
2007-02-03 16:30         ` Sergei Shtylyov
2007-01-22 18:17   ` Sergei Shtylyov
2007-01-22 18:46     ` Alan
2007-01-22 20:28       ` Sergei Shtylyov
2007-01-22 21:31         ` Alan
2007-01-22 22:39           ` Jeff Garzik
     [not found]             ` <45B6071C.90703@ru.mvista.com>
     [not found]               ` <45B761F8.1060505@ru.mvista.com>
2007-01-25 22:20                 ` Updated SiI h/w docs (was Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks) Jeff Garzik
2007-01-26 13:14                   ` Sergei Shtylyov
2007-01-23 14:51           ` [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks Sergei Shtylyov
2007-01-25 15:40             ` Sergei Shtylyov
2007-01-31 20:38       ` Sergei Shtylyov
2007-01-31 23:24         ` Alan
     [not found]     ` <58cb370e0702021606m4eb6f682xfa4bf769d398cf9@mail.gmail.com>
2007-02-03  0:50       ` Bartlomiej Zolnierkiewicz
2007-01-19  0:32 ` [PATCH 14/15] ide: rework the code for selecting the best DMA transfer mode Bartlomiej Zolnierkiewicz
2007-01-22 19:48   ` Sergei Shtylyov
     [not found]     ` <58cb370e0702021207o435f39cdsf3abb0d55829fc45@mail.gmail.com>
2007-02-02 23:57       ` Bartlomiej Zolnierkiewicz
2007-01-19  0:32 ` [PATCH 15/15] ide: add ide_tune_dma() helper Bartlomiej Zolnierkiewicz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.