[kernel] r7456 - in people/dannf/kernel-source-2.6.8-2.6.8/debian: . patches patches/series

Dann Frazier dannf at costa.debian.org
Mon Sep 18 22:12:13 UTC 2006


Author: dannf
Date: Mon Sep 18 22:12:12 2006
New Revision: 7456

Added:
   people/dannf/kernel-source-2.6.8-2.6.8/debian/patches/ata-update-to-2.6.10.dpatch
Modified:
   people/dannf/kernel-source-2.6.8-2.6.8/debian/changelog
   people/dannf/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-16sarge5dannf1

Log:
* ata-update-to-2.6.10.dpatch
  Backport the ata subsystem from 2.6.10, adding support for new devices - this patch will need some organized testing

Modified: people/dannf/kernel-source-2.6.8-2.6.8/debian/changelog
==============================================================================
--- people/dannf/kernel-source-2.6.8-2.6.8/debian/changelog	(original)
+++ people/dannf/kernel-source-2.6.8-2.6.8/debian/changelog	Mon Sep 18 22:12:12 2006
@@ -12,8 +12,10 @@
     Update e1000 driver to 6.2.15 to add support for new devices
   * cciss_2.6.2_to_2.6.10.dpatch
     Update cciss driver to 2.6.10 to add support for new devices
+  * ata-update-to-2.6.10.dpatch
+    Backport the ata subsystem from 2.6.10, adding support for new devices
 
- -- dann frazier <dannf at debian.org>  Mon, 18 Sep 2006 15:53:31 -0600
+ -- dann frazier <dannf at debian.org>  Mon, 18 Sep 2006 16:09:32 -0600
 
 kernel-source-2.6.8 (2.6.8-16sarge5) stable-security; urgency=high
 

Added: people/dannf/kernel-source-2.6.8-2.6.8/debian/patches/ata-update-to-2.6.10.dpatch
==============================================================================
--- (empty file)
+++ people/dannf/kernel-source-2.6.8-2.6.8/debian/patches/ata-update-to-2.6.10.dpatch	Mon Sep 18 22:12:12 2006
@@ -0,0 +1,9639 @@
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/media/dvb/frontends/dst.c kernel-source-2.6.8-2.6.8/drivers/media/dvb/frontends/dst.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/media/dvb/frontends/dst.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/media/dvb/frontends/dst.c	2006-08-11 14:32:25.445656776 -0600
+@@ -1145,8 +1145,8 @@
+ 	}
+ 
+ 	dst_init (dst);
+-	dprintk("%s: register dst %8.8x bt %8.8x i2c %8.8x\n", __FUNCTION__, 
+-			(u32)dst, (u32)(dst->bt), (u32)(dst->i2c));
++	dprintk("%s: register dst %p bt %p i2c %p\n", __FUNCTION__, 
++			dst, dst->bt, dst->i2c);
+ 
+ 	info = &dst_info_sat;
+ 	if (dst->dst_type == DST_TYPE_IS_TERR)
+@@ -1162,7 +1162,7 @@
+ static void dst_detach (struct dvb_i2c_bus *i2c, void *data)
+ {
+ 	dvb_unregister_frontend (dst_ioctl, i2c);
+-	dprintk("%s: unregister dst %8.8x\n", __FUNCTION__, (u32)(data));
++	dprintk("%s: unregister dst %p\n", __FUNCTION__, data);
+ 	if (data)
+ 		kfree(data);
+ }
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/media/video/zoran_driver.c kernel-source-2.6.8-2.6.8/drivers/media/video/zoran_driver.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/media/video/zoran_driver.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/media/video/zoran_driver.c	2006-08-11 14:32:25.448587073 -0600
+@@ -2265,8 +2265,8 @@
+ 
+ 		dprintk(3,
+ 			KERN_DEBUG
+-			"%s: VIDIOCSFBUF - base=0x%x, w=%d, h=%d, depth=%d, bpl=%d\n",
+-			ZR_DEVNAME(zr), (u32) vbuf->base, vbuf->width,
++			"%s: VIDIOCSFBUF - base=%p, w=%d, h=%d, depth=%d, bpl=%d\n",
++			ZR_DEVNAME(zr), vbuf->base, vbuf->width,
+ 			vbuf->height, vbuf->depth, vbuf->bytesperline);
+ 
+ 		for (i = 0; i < zoran_num_formats; i++)
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/Kconfig kernel-source-2.6.8-2.6.8/drivers/scsi/Kconfig
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/Kconfig	2006-08-11 14:32:57.351712432 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/Kconfig	2006-08-11 14:32:25.348956959 -0600
+@@ -425,16 +425,24 @@
+ 
+ config SCSI_SATA
+ 	bool "Serial ATA (SATA) support"
+-	depends on SCSI && EXPERIMENTAL
++	depends on SCSI
+ 	help
+ 	  This driver family supports Serial ATA host controllers
+ 	  and devices.
+ 
+ 	  If unsure, say N.
+ 
++config SCSI_SATA_AHCI
++	tristate "AHCI SATA support"
++	depends on SCSI_SATA && PCI
++	help
++	  This option enables support for AHCI Serial ATA.
++
++	  If unsure, say N.
++
+ config SCSI_SATA_SVW
+-	tristate "ServerWorks Frodo / Apple K2 SATA support (EXPERIMENTAL)"
+-	depends on SCSI_SATA && PCI && EXPERIMENTAL
++	tristate "ServerWorks Frodo / Apple K2 SATA support"
++	depends on SCSI_SATA && PCI
+ 	help
+ 	  This option enables support for Broadcom/Serverworks/Apple K2
+ 	  SATA support.
+@@ -485,15 +493,23 @@
+ 
+ config SCSI_SATA_SIS
+ 	tristate "SiS 964/180 SATA support"
+-	depends on SCSI_SATA && PCI
++	depends on SCSI_SATA && PCI && EXPERIMENTAL
+ 	help
+ 	  This option enables support for SiS Serial ATA 964/180.
+ 
+ 	  If unsure, say N.
+ 
++config SCSI_SATA_ULI
++	tristate "ULi Electronics SATA support"
++	depends on SCSI_SATA && PCI && EXPERIMENTAL
++	help
++	  This option enables support for ULi Electronics SATA.
++
++	  If unsure, say N.
++
+ config SCSI_SATA_VIA
+ 	tristate "VIA SATA support"
+-	depends on SCSI_SATA && PCI && EXPERIMENTAL
++	depends on SCSI_SATA && PCI
+ 	help
+ 	  This option enables support for VIA Serial ATA.
+ 
+@@ -501,7 +517,7 @@
+ 
+ config SCSI_SATA_VITESSE
+ 	tristate "VITESSE VSC-7174 SATA support"
+-	depends on SCSI_SATA && PCI && EXPERIMENTAL
++	depends on SCSI_SATA && PCI
+ 	help
+ 	  This option enables support for Vitesse VSC7174 Serial ATA.
+ 
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/Makefile kernel-source-2.6.8-2.6.8/drivers/scsi/Makefile
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/Makefile	2006-08-11 14:32:54.741794147 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/Makefile	2006-08-11 14:32:25.141882605 -0600
+@@ -118,6 +118,7 @@
+ obj-$(CONFIG_SCSI_LASI700)	+= 53c700.o lasi700.o
+ obj-$(CONFIG_SCSI_NSP32)	+= nsp32.o
+ obj-$(CONFIG_SCSI_IPR)		+= ipr.o
++obj-$(CONFIG_SCSI_SATA_AHCI)	+= libata.o ahci.o
+ obj-$(CONFIG_SCSI_SATA_SVW)	+= libata.o sata_svw.o
+ obj-$(CONFIG_SCSI_ATA_PIIX)	+= libata.o ata_piix.o
+ obj-$(CONFIG_SCSI_SATA_PROMISE)	+= libata.o sata_promise.o
+@@ -127,6 +128,7 @@
+ obj-$(CONFIG_SCSI_SATA_SIS)	+= libata.o sata_sis.o
+ obj-$(CONFIG_SCSI_SATA_SX4)	+= libata.o sata_sx4.o
+ obj-$(CONFIG_SCSI_SATA_NV)	+= libata.o sata_nv.o
++obj-$(CONFIG_SCSI_SATA_ULI)	+= libata.o sata_uli.o
+ 
+ obj-$(CONFIG_ARM)		+= arm/
+ 
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/ahci.c kernel-source-2.6.8-2.6.8/drivers/scsi/ahci.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/ahci.c	1969-12-31 17:00:00.000000000 -0700
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/ahci.c	2006-08-11 14:32:25.401702314 -0600
+@@ -0,0 +1,1040 @@
++/*
++ *  ahci.c - AHCI SATA support
++ *
++ *  Copyright 2004 Red Hat, Inc.
++ *
++ *  The contents of this file are subject to the Open
++ *  Software License version 1.1 that can be found at
++ *  http://www.opensource.org/licenses/osl-1.1.txt and is included herein
++ *  by reference.
++ *
++ *  Alternatively, the contents of this file may be used under the terms
++ *  of the GNU General Public License version 2 (the "GPL") as distributed
++ *  in the kernel source COPYING file, in which case the provisions of
++ *  the GPL are applicable instead of the above.  If you wish to allow
++ *  the use of your version of this file only under the terms of the
++ *  GPL and not to allow others to use your version of this file under
++ *  the OSL, indicate your decision by deleting the provisions above and
++ *  replace them with the notice and other provisions required by the GPL.
++ *  If you do not delete the provisions above, a recipient may use your
++ *  version of this file under either the OSL or the GPL.
++ *
++ * Version 1.0 of the AHCI specification:
++ * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/blkdev.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include "scsi.h"
++#include <scsi/scsi_host.h>
++#include <linux/libata.h>
++#include <asm/io.h>
++
++#define DRV_NAME	"ahci"
++#define DRV_VERSION	"1.00"
++
++
++enum {
++	AHCI_PCI_BAR		= 5,
++	AHCI_MAX_SG		= 168, /* hardware max is 64K */
++	AHCI_DMA_BOUNDARY	= 0xffffffff,
++	AHCI_USE_CLUSTERING	= 0,
++	AHCI_CMD_SLOT_SZ	= 32 * 32,
++	AHCI_RX_FIS_SZ		= 256,
++	AHCI_CMD_TBL_HDR	= 0x80,
++	AHCI_CMD_TBL_SZ		= AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16),
++	AHCI_PORT_PRIV_DMA_SZ	= AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ +
++				  AHCI_RX_FIS_SZ,
++	AHCI_IRQ_ON_SG		= (1 << 31),
++	AHCI_CMD_ATAPI		= (1 << 5),
++	AHCI_CMD_WRITE		= (1 << 6),
++
++	RX_FIS_D2H_REG		= 0x40,	/* offset of D2H Register FIS data */
++
++	board_ahci		= 0,
++
++	/* global controller registers */
++	HOST_CAP		= 0x00, /* host capabilities */
++	HOST_CTL		= 0x04, /* global host control */
++	HOST_IRQ_STAT		= 0x08, /* interrupt status */
++	HOST_PORTS_IMPL		= 0x0c, /* bitmap of implemented ports */
++	HOST_VERSION		= 0x10, /* AHCI spec. version compliancy */
++
++	/* HOST_CTL bits */
++	HOST_RESET		= (1 << 0),  /* reset controller; self-clear */
++	HOST_IRQ_EN		= (1 << 1),  /* global IRQ enable */
++	HOST_AHCI_EN		= (1 << 31), /* AHCI enabled */
++
++	/* HOST_CAP bits */
++	HOST_CAP_64		= (1 << 31), /* PCI DAC (64-bit DMA) support */
++
++	/* registers for each SATA port */
++	PORT_LST_ADDR		= 0x00, /* command list DMA addr */
++	PORT_LST_ADDR_HI	= 0x04, /* command list DMA addr hi */
++	PORT_FIS_ADDR		= 0x08, /* FIS rx buf addr */
++	PORT_FIS_ADDR_HI	= 0x0c, /* FIS rx buf addr hi */
++	PORT_IRQ_STAT		= 0x10, /* interrupt status */
++	PORT_IRQ_MASK		= 0x14, /* interrupt enable/disable mask */
++	PORT_CMD		= 0x18, /* port command */
++	PORT_TFDATA		= 0x20,	/* taskfile data */
++	PORT_SIG		= 0x24,	/* device TF signature */
++	PORT_CMD_ISSUE		= 0x38, /* command issue */
++	PORT_SCR		= 0x28, /* SATA phy register block */
++	PORT_SCR_STAT		= 0x28, /* SATA phy register: SStatus */
++	PORT_SCR_CTL		= 0x2c, /* SATA phy register: SControl */
++	PORT_SCR_ERR		= 0x30, /* SATA phy register: SError */
++	PORT_SCR_ACT		= 0x34, /* SATA phy register: SActive */
++
++	/* PORT_IRQ_{STAT,MASK} bits */
++	PORT_IRQ_COLD_PRES	= (1 << 31), /* cold presence detect */
++	PORT_IRQ_TF_ERR		= (1 << 30), /* task file error */
++	PORT_IRQ_HBUS_ERR	= (1 << 29), /* host bus fatal error */
++	PORT_IRQ_HBUS_DATA_ERR	= (1 << 28), /* host bus data error */
++	PORT_IRQ_IF_ERR		= (1 << 27), /* interface fatal error */
++	PORT_IRQ_IF_NONFATAL	= (1 << 26), /* interface non-fatal error */
++	PORT_IRQ_OVERFLOW	= (1 << 24), /* xfer exhausted available S/G */
++	PORT_IRQ_BAD_PMP	= (1 << 23), /* incorrect port multiplier */
++
++	PORT_IRQ_PHYRDY		= (1 << 22), /* PhyRdy changed */
++	PORT_IRQ_DEV_ILCK	= (1 << 7), /* device interlock */
++	PORT_IRQ_CONNECT	= (1 << 6), /* port connect change status */
++	PORT_IRQ_SG_DONE	= (1 << 5), /* descriptor processed */
++	PORT_IRQ_UNK_FIS	= (1 << 4), /* unknown FIS rx'd */
++	PORT_IRQ_SDB_FIS	= (1 << 3), /* Set Device Bits FIS rx'd */
++	PORT_IRQ_DMAS_FIS	= (1 << 2), /* DMA Setup FIS rx'd */
++	PORT_IRQ_PIOS_FIS	= (1 << 1), /* PIO Setup FIS rx'd */
++	PORT_IRQ_D2H_REG_FIS	= (1 << 0), /* D2H Register FIS rx'd */
++
++	PORT_IRQ_FATAL		= PORT_IRQ_TF_ERR |
++				  PORT_IRQ_HBUS_ERR |
++				  PORT_IRQ_HBUS_DATA_ERR |
++				  PORT_IRQ_IF_ERR,
++	DEF_PORT_IRQ		= PORT_IRQ_FATAL | PORT_IRQ_PHYRDY |
++				  PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE |
++				  PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS |
++				  PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS |
++				  PORT_IRQ_D2H_REG_FIS,
++
++	/* PORT_CMD bits */
++	PORT_CMD_LIST_ON	= (1 << 15), /* cmd list DMA engine running */
++	PORT_CMD_FIS_ON		= (1 << 14), /* FIS DMA engine running */
++	PORT_CMD_FIS_RX		= (1 << 4), /* Enable FIS receive DMA engine */
++	PORT_CMD_POWER_ON	= (1 << 2), /* Power up device */
++	PORT_CMD_SPIN_UP	= (1 << 1), /* Spin up device */
++	PORT_CMD_START		= (1 << 0), /* Enable port DMA engine */
++
++	PORT_CMD_ICC_ACTIVE	= (0x1 << 28), /* Put i/f in active state */
++	PORT_CMD_ICC_PARTIAL	= (0x2 << 28), /* Put i/f in partial state */
++	PORT_CMD_ICC_SLUMBER	= (0x6 << 28), /* Put i/f in slumber state */
++};
++
++struct ahci_cmd_hdr {
++	u32			opts;
++	u32			status;
++	u32			tbl_addr;
++	u32			tbl_addr_hi;
++	u32			reserved[4];
++};
++
++struct ahci_sg {
++	u32			addr;
++	u32			addr_hi;
++	u32			reserved;
++	u32			flags_size;
++};
++
++struct ahci_host_priv {
++	unsigned long		flags;
++	u32			cap;	/* cache of HOST_CAP register */
++	u32			port_map; /* cache of HOST_PORTS_IMPL reg */
++};
++
++struct ahci_port_priv {
++	struct ahci_cmd_hdr	*cmd_slot;
++	dma_addr_t		cmd_slot_dma;
++	void			*cmd_tbl;
++	dma_addr_t		cmd_tbl_dma;
++	struct ahci_sg		*cmd_tbl_sg;
++	void			*rx_fis;
++	dma_addr_t		rx_fis_dma;
++};
++
++static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
++static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
++static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
++static int ahci_qc_issue(struct ata_queued_cmd *qc);
++static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
++static void ahci_phy_reset(struct ata_port *ap);
++static void ahci_irq_clear(struct ata_port *ap);
++static void ahci_eng_timeout(struct ata_port *ap);
++static int ahci_port_start(struct ata_port *ap);
++static void ahci_port_stop(struct ata_port *ap);
++static void ahci_host_stop(struct ata_host_set *host_set);
++static void ahci_qc_prep(struct ata_queued_cmd *qc);
++static u8 ahci_check_status(struct ata_port *ap);
++static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
++
++static Scsi_Host_Template ahci_sht = {
++	.module			= THIS_MODULE,
++	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
++	.queuecommand		= ata_scsi_queuecmd,
++	.eh_strategy_handler	= ata_scsi_error,
++	.can_queue		= ATA_DEF_QUEUE,
++	.this_id		= ATA_SHT_THIS_ID,
++	.sg_tablesize		= AHCI_MAX_SG,
++	.max_sectors		= ATA_MAX_SECTORS,
++	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
++	.emulated		= ATA_SHT_EMULATED,
++	.use_clustering		= AHCI_USE_CLUSTERING,
++	.proc_name		= DRV_NAME,
++	.dma_boundary		= AHCI_DMA_BOUNDARY,
++	.slave_configure	= ata_scsi_slave_config,
++	.bios_param		= ata_std_bios_param,
++};
++
++static struct ata_port_operations ahci_ops = {
++	.port_disable		= ata_port_disable,
++
++	.check_status		= ahci_check_status,
++	.dev_select		= ata_noop_dev_select,
++
++	.phy_reset		= ahci_phy_reset,
++
++	.qc_prep		= ahci_qc_prep,
++	.qc_issue		= ahci_qc_issue,
++
++	.eng_timeout		= ahci_eng_timeout,
++
++	.irq_handler		= ahci_interrupt,
++	.irq_clear		= ahci_irq_clear,
++
++	.scr_read		= ahci_scr_read,
++	.scr_write		= ahci_scr_write,
++
++	.port_start		= ahci_port_start,
++	.port_stop		= ahci_port_stop,
++	.host_stop		= ahci_host_stop,
++};
++
++static struct ata_port_info ahci_port_info[] = {
++	/* board_ahci */
++	{
++		.sht		= &ahci_sht,
++		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
++				  ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
++				  ATA_FLAG_PIO_DMA,
++		.pio_mask	= 0x03, /* pio3-4 */
++		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
++		.port_ops	= &ahci_ops,
++	},
++};
++
++static struct pci_device_id ahci_pci_tbl[] = {
++	{ PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
++	  board_ahci },
++	{ PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
++	  board_ahci },
++	{ }	/* terminate list */
++};
++
++
++static struct pci_driver ahci_pci_driver = {
++	.name			= DRV_NAME,
++	.id_table		= ahci_pci_tbl,
++	.probe			= ahci_init_one,
++	.remove			= ata_pci_remove_one,
++};
++
++
++static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port)
++{
++	return base + 0x100 + (port * 0x80);
++}
++
++static inline void *ahci_port_base (void *base, unsigned int port)
++{
++	return (void *) ahci_port_base_ul((unsigned long)base, port);
++}
++
++static void ahci_host_stop(struct ata_host_set *host_set)
++{
++	struct ahci_host_priv *hpriv = host_set->private_data;
++	kfree(hpriv);
++}
++
++static int ahci_port_start(struct ata_port *ap)
++{
++	struct device *dev = ap->host_set->dev;
++	struct ahci_host_priv *hpriv = ap->host_set->private_data;
++	struct ahci_port_priv *pp;
++	int rc;
++	void *mem, *mmio = ap->host_set->mmio_base;
++	void *port_mmio = ahci_port_base(mmio, ap->port_no);
++	dma_addr_t mem_dma;
++
++	rc = ata_port_start(ap);
++	if (rc)
++		return rc;
++
++	pp = kmalloc(sizeof(*pp), GFP_KERNEL);
++	if (!pp) {
++		rc = -ENOMEM;
++		goto err_out;
++	}
++	memset(pp, 0, sizeof(*pp));
++
++	mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
++	if (!mem) {
++		rc = -ENOMEM;
++		goto err_out_kfree;
++	}
++	memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
++
++	/*
++	 * First item in chunk of DMA memory: 32-slot command table,
++	 * 32 bytes each in size
++	 */
++	pp->cmd_slot = mem;
++	pp->cmd_slot_dma = mem_dma;
++
++	mem += AHCI_CMD_SLOT_SZ;
++	mem_dma += AHCI_CMD_SLOT_SZ;
++
++	/*
++	 * Second item: Received-FIS area
++	 */
++	pp->rx_fis = mem;
++	pp->rx_fis_dma = mem_dma;
++
++	mem += AHCI_RX_FIS_SZ;
++	mem_dma += AHCI_RX_FIS_SZ;
++
++	/*
++	 * Third item: data area for storing a single command
++	 * and its scatter-gather table
++	 */
++	pp->cmd_tbl = mem;
++	pp->cmd_tbl_dma = mem_dma;
++
++	pp->cmd_tbl_sg = mem + AHCI_CMD_TBL_HDR;
++
++	ap->private_data = pp;
++
++	if (hpriv->cap & HOST_CAP_64)
++		writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI);
++	writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
++	readl(port_mmio + PORT_LST_ADDR); /* flush */
++
++	if (hpriv->cap & HOST_CAP_64)
++		writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI);
++	writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
++	readl(port_mmio + PORT_FIS_ADDR); /* flush */
++
++	writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
++	       PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
++	       PORT_CMD_START, port_mmio + PORT_CMD);
++	readl(port_mmio + PORT_CMD); /* flush */
++
++	return 0;
++
++err_out_kfree:
++	kfree(pp);
++err_out:
++	ata_port_stop(ap);
++	return rc;
++}
++
++
++static void ahci_port_stop(struct ata_port *ap)
++{
++	struct device *dev = ap->host_set->dev;
++	struct ahci_port_priv *pp = ap->private_data;
++	void *mmio = ap->host_set->mmio_base;
++	void *port_mmio = ahci_port_base(mmio, ap->port_no);
++	u32 tmp;
++
++	tmp = readl(port_mmio + PORT_CMD);
++	tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX);
++	writel(tmp, port_mmio + PORT_CMD);
++	readl(port_mmio + PORT_CMD); /* flush */
++
++	/* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so
++	 * this is slightly incorrect.
++	 */
++	msleep(500);
++
++	ap->private_data = NULL;
++	dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
++			  pp->cmd_slot, pp->cmd_slot_dma);
++	kfree(pp);
++	ata_port_stop(ap);
++}
++
++static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
++{
++	unsigned int sc_reg;
++
++	switch (sc_reg_in) {
++	case SCR_STATUS:	sc_reg = 0; break;
++	case SCR_CONTROL:	sc_reg = 1; break;
++	case SCR_ERROR:		sc_reg = 2; break;
++	case SCR_ACTIVE:	sc_reg = 3; break;
++	default:
++		return 0xffffffffU;
++	}
++
++	return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
++}
++
++
++static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
++			       u32 val)
++{
++	unsigned int sc_reg;
++
++	switch (sc_reg_in) {
++	case SCR_STATUS:	sc_reg = 0; break;
++	case SCR_CONTROL:	sc_reg = 1; break;
++	case SCR_ERROR:		sc_reg = 2; break;
++	case SCR_ACTIVE:	sc_reg = 3; break;
++	default:
++		return;
++	}
++
++	writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
++}
++
++static void ahci_phy_reset(struct ata_port *ap)
++{
++	void *port_mmio = (void *) ap->ioaddr.cmd_addr;
++	struct ata_taskfile tf;
++	struct ata_device *dev = &ap->device[0];
++	u32 tmp;
++
++	__sata_phy_reset(ap);
++
++	if (ap->flags & ATA_FLAG_PORT_DISABLED)
++		return;
++
++	tmp = readl(port_mmio + PORT_SIG);
++	tf.lbah		= (tmp >> 24)	& 0xff;
++	tf.lbam		= (tmp >> 16)	& 0xff;
++	tf.lbal		= (tmp >> 8)	& 0xff;
++	tf.nsect	= (tmp)		& 0xff;
++
++	dev->class = ata_dev_classify(&tf);
++	if (!ata_dev_present(dev))
++		ata_port_disable(ap);
++}
++
++static u8 ahci_check_status(struct ata_port *ap)
++{
++	void *mmio = (void *) ap->ioaddr.cmd_addr;
++
++	return readl(mmio + PORT_TFDATA) & 0xFF;
++}
++
++static void ahci_fill_sg(struct ata_queued_cmd *qc)
++{
++	struct ahci_port_priv *pp = qc->ap->private_data;
++	unsigned int i;
++
++	VPRINTK("ENTER\n");
++
++	/*
++	 * Next, the S/G list.
++	 */
++	for (i = 0; i < qc->n_elem; i++) {
++		u32 sg_len;
++		dma_addr_t addr;
++
++		addr = sg_dma_address(&qc->sg[i]);
++		sg_len = sg_dma_len(&qc->sg[i]);
++
++		pp->cmd_tbl_sg[i].addr = cpu_to_le32(addr & 0xffffffff);
++		pp->cmd_tbl_sg[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
++		pp->cmd_tbl_sg[i].flags_size = cpu_to_le32(sg_len - 1);
++	}
++}
++
++static void ahci_qc_prep(struct ata_queued_cmd *qc)
++{
++	struct ahci_port_priv *pp = qc->ap->private_data;
++	u32 opts;
++	const u32 cmd_fis_len = 5; /* five dwords */
++
++	/*
++	 * Fill in command slot information (currently only one slot,
++	 * slot 0, is currently since we don't do queueing)
++	 */
++
++	opts = (qc->n_elem << 16) | cmd_fis_len;
++	if (qc->tf.flags & ATA_TFLAG_WRITE)
++		opts |= AHCI_CMD_WRITE;
++
++	switch (qc->tf.protocol) {
++	case ATA_PROT_ATAPI:
++	case ATA_PROT_ATAPI_NODATA:
++	case ATA_PROT_ATAPI_DMA:
++		opts |= AHCI_CMD_ATAPI;
++		break;
++
++	default:
++		/* do nothing */
++		break;
++	}
++
++	pp->cmd_slot[0].opts = cpu_to_le32(opts);
++	pp->cmd_slot[0].status = 0;
++	pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff);
++	pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
++
++	/*
++	 * Fill in command table information.  First, the header,
++	 * a SATA Register - Host to Device command FIS.
++	 */
++	ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0);
++
++	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
++		return;
++
++	ahci_fill_sg(qc);
++}
++
++static inline void ahci_dma_complete (struct ata_port *ap,
++                                     struct ata_queued_cmd *qc,
++				     int have_err)
++{
++	/* get drive status; clear intr; complete txn */
++	ata_qc_complete(ata_qc_from_tag(ap, ap->active_tag),
++			have_err ? ATA_ERR : 0);
++}
++
++static void ahci_intr_error(struct ata_port *ap, u32 irq_stat)
++{
++	void *mmio = ap->host_set->mmio_base;
++	void *port_mmio = ahci_port_base(mmio, ap->port_no);
++	u32 tmp;
++	int work;
++
++	/* stop DMA */
++	tmp = readl(port_mmio + PORT_CMD);
++	tmp &= PORT_CMD_START | PORT_CMD_FIS_RX;
++	writel(tmp, port_mmio + PORT_CMD);
++
++	/* wait for engine to stop.  TODO: this could be
++	 * as long as 500 msec
++	 */
++	work = 1000;
++	while (work-- > 0) {
++		tmp = readl(port_mmio + PORT_CMD);
++		if ((tmp & PORT_CMD_LIST_ON) == 0)
++			break;
++		udelay(10);
++	}
++
++	/* clear SATA phy error, if any */
++	tmp = readl(port_mmio + PORT_SCR_ERR);
++	writel(tmp, port_mmio + PORT_SCR_ERR);
++
++	/* if DRQ/BSY is set, device needs to be reset.
++	 * if so, issue COMRESET
++	 */
++	tmp = readl(port_mmio + PORT_TFDATA);
++	if (tmp & (ATA_BUSY | ATA_DRQ)) {
++		writel(0x301, port_mmio + PORT_SCR_CTL);
++		readl(port_mmio + PORT_SCR_CTL); /* flush */
++		udelay(10);
++		writel(0x300, port_mmio + PORT_SCR_CTL);
++		readl(port_mmio + PORT_SCR_CTL); /* flush */
++	}
++
++	/* re-start DMA */
++	tmp = readl(port_mmio + PORT_CMD);
++	tmp |= PORT_CMD_START | PORT_CMD_FIS_RX;
++	writel(tmp, port_mmio + PORT_CMD);
++	readl(port_mmio + PORT_CMD); /* flush */
++
++	printk(KERN_WARNING "ata%u: error occurred, port reset\n", ap->port_no);
++}
++
++static void ahci_eng_timeout(struct ata_port *ap)
++{
++	void *mmio = ap->host_set->mmio_base;
++	void *port_mmio = ahci_port_base(mmio, ap->port_no);
++	struct ata_queued_cmd *qc;
++
++	DPRINTK("ENTER\n");
++
++	ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT));
++
++	qc = ata_qc_from_tag(ap, ap->active_tag);
++	if (!qc) {
++		printk(KERN_ERR "ata%u: BUG: timeout without command\n",
++		       ap->id);
++	} else {
++		/* hack alert!  We cannot use the supplied completion
++	 	 * function from inside the ->eh_strategy_handler() thread.
++	 	 * libata is the only user of ->eh_strategy_handler() in
++	 	 * any kernel, so the default scsi_done() assumes it is
++	 	 * not being called from the SCSI EH.
++	 	 */
++		qc->scsidone = scsi_finish_command;
++		ata_qc_complete(qc, ATA_ERR);
++	}
++
++}
++
++static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
++{
++	void *mmio = ap->host_set->mmio_base;
++	void *port_mmio = ahci_port_base(mmio, ap->port_no);
++	u32 status, serr, ci;
++
++	serr = readl(port_mmio + PORT_SCR_ERR);
++	writel(serr, port_mmio + PORT_SCR_ERR);
++
++	status = readl(port_mmio + PORT_IRQ_STAT);
++	writel(status, port_mmio + PORT_IRQ_STAT);
++
++	ci = readl(port_mmio + PORT_CMD_ISSUE);
++	if (likely((ci & 0x1) == 0)) {
++		if (qc) {
++			ata_qc_complete(qc, 0);
++			qc = NULL;
++		}
++	}
++
++	if (status & PORT_IRQ_FATAL) {
++		ahci_intr_error(ap, status);
++		if (qc)
++			ata_qc_complete(qc, ATA_ERR);
++	}
++
++	return 1;
++}
++
++static void ahci_irq_clear(struct ata_port *ap)
++{
++	/* TODO */
++}
++
++static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
++{
++	struct ata_host_set *host_set = dev_instance;
++	struct ahci_host_priv *hpriv;
++	unsigned int i, handled = 0;
++	void *mmio;
++	u32 irq_stat, irq_ack = 0;
++
++	VPRINTK("ENTER\n");
++
++	hpriv = host_set->private_data;
++	mmio = host_set->mmio_base;
++
++	/* sigh.  0xffffffff is a valid return from h/w */
++	irq_stat = readl(mmio + HOST_IRQ_STAT);
++	irq_stat &= hpriv->port_map;
++	if (!irq_stat)
++		return IRQ_NONE;
++
++        spin_lock(&host_set->lock);
++
++        for (i = 0; i < host_set->n_ports; i++) {
++		struct ata_port *ap;
++		u32 tmp;
++
++		VPRINTK("port %u\n", i);
++		ap = host_set->ports[i];
++		tmp = irq_stat & (1 << i);
++		if (tmp && ap) {
++			struct ata_queued_cmd *qc;
++			qc = ata_qc_from_tag(ap, ap->active_tag);
++			if (ahci_host_intr(ap, qc))
++				irq_ack |= (1 << i);
++		}
++	}
++
++	if (irq_ack) {
++		writel(irq_ack, mmio + HOST_IRQ_STAT);
++		handled = 1;
++	}
++
++        spin_unlock(&host_set->lock);
++
++	VPRINTK("EXIT\n");
++
++	return IRQ_RETVAL(handled);
++}
++
++static int ahci_qc_issue(struct ata_queued_cmd *qc)
++{
++	struct ata_port *ap = qc->ap;
++	void *port_mmio = (void *) ap->ioaddr.cmd_addr;
++
++	writel(1, port_mmio + PORT_SCR_ACT);
++	readl(port_mmio + PORT_SCR_ACT);	/* flush */
++
++	writel(1, port_mmio + PORT_CMD_ISSUE);
++	readl(port_mmio + PORT_CMD_ISSUE);	/* flush */
++
++	return 0;
++}
++
++static void ahci_setup_port(struct ata_ioports *port, unsigned long base,
++			    unsigned int port_idx)
++{
++	VPRINTK("ENTER, base==0x%lx, port_idx %u\n", base, port_idx);
++	base = ahci_port_base_ul(base, port_idx);
++	VPRINTK("base now==0x%lx\n", base);
++
++	port->cmd_addr		= base;
++	port->scr_addr		= base + PORT_SCR;
++
++	VPRINTK("EXIT\n");
++}
++
++static int ahci_host_init(struct ata_probe_ent *probe_ent)
++{
++	struct ahci_host_priv *hpriv = probe_ent->private_data;
++	struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
++	void *mmio = probe_ent->mmio_base;
++	u32 tmp, cap_save;
++	u16 tmp16;
++	unsigned int i, j, using_dac;
++	int rc;
++	void *port_mmio;
++
++	cap_save = readl(mmio + HOST_CAP);
++	cap_save &= ( (1<<28) | (1<<17) );
++	cap_save |= (1 << 27);
++
++	/* global controller reset */
++	tmp = readl(mmio + HOST_CTL);
++	if ((tmp & HOST_RESET) == 0) {
++		writel(tmp | HOST_RESET, mmio + HOST_CTL);
++		readl(mmio + HOST_CTL); /* flush */
++	}
++
++	/* reset must complete within 1 second, or
++	 * the hardware should be considered fried.
++	 */
++	ssleep(1);
++
++	tmp = readl(mmio + HOST_CTL);
++	if (tmp & HOST_RESET) {
++		printk(KERN_ERR DRV_NAME "(%s): controller reset failed (0x%x)\n",
++			pci_name(pdev), tmp);
++		return -EIO;
++	}
++
++	writel(HOST_AHCI_EN, mmio + HOST_CTL);
++	(void) readl(mmio + HOST_CTL);	/* flush */
++	writel(cap_save, mmio + HOST_CAP);
++	writel(0xf, mmio + HOST_PORTS_IMPL);
++	(void) readl(mmio + HOST_PORTS_IMPL);	/* flush */
++
++	pci_read_config_word(pdev, 0x92, &tmp16);
++	tmp16 |= 0xf;
++	pci_write_config_word(pdev, 0x92, tmp16);
++
++	hpriv->cap = readl(mmio + HOST_CAP);
++	hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
++	probe_ent->n_ports = (hpriv->cap & 0x1f) + 1;
++
++	VPRINTK("cap 0x%x  port_map 0x%x  n_ports %d\n",
++		hpriv->cap, hpriv->port_map, probe_ent->n_ports);
++
++	using_dac = hpriv->cap & HOST_CAP_64;
++	if (using_dac &&
++	    !pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
++		rc = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
++		if (rc) {
++			rc = pci_set_consistent_dma_mask(pdev, 0xffffffffULL);
++			if (rc) {
++				printk(KERN_ERR DRV_NAME "(%s): 64-bit DMA enable failed\n",
++					pci_name(pdev));
++				return rc;
++			}
++		}
++
++		hpriv->flags |= HOST_CAP_64;
++	} else {
++		rc = pci_set_dma_mask(pdev, 0xffffffffULL);
++		if (rc) {
++			printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n",
++				pci_name(pdev));
++			return rc;
++		}
++		rc = pci_set_consistent_dma_mask(pdev, 0xffffffffULL);
++		if (rc) {
++			printk(KERN_ERR DRV_NAME "(%s): 32-bit consistent DMA enable failed\n",
++				pci_name(pdev));
++			return rc;
++		}
++	}
++
++	for (i = 0; i < probe_ent->n_ports; i++) {
++#if 0 /* BIOSen initialize this incorrectly */
++		if (!(hpriv->port_map & (1 << i)))
++			continue;
++#endif
++
++		port_mmio = ahci_port_base(mmio, i);
++		VPRINTK("mmio %p  port_mmio %p\n", mmio, port_mmio);
++
++		ahci_setup_port(&probe_ent->port[i],
++				(unsigned long) mmio, i);
++
++		/* make sure port is not active */
++		tmp = readl(port_mmio + PORT_CMD);
++		VPRINTK("PORT_CMD 0x%x\n", tmp);
++		if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
++			   PORT_CMD_FIS_RX | PORT_CMD_START)) {
++			tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
++				 PORT_CMD_FIS_RX | PORT_CMD_START);
++			writel(tmp, port_mmio + PORT_CMD);
++			readl(port_mmio + PORT_CMD); /* flush */
++
++			/* spec says 500 msecs for each bit, so
++			 * this is slightly incorrect.
++			 */
++			msleep(500);
++		}
++
++		writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD);
++
++		j = 0;
++		while (j < 100) {
++			msleep(10);
++			tmp = readl(port_mmio + PORT_SCR_STAT);
++			if ((tmp & 0xf) == 0x3)
++				break;
++			j++;
++		}
++
++		tmp = readl(port_mmio + PORT_SCR_ERR);
++		VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
++		writel(tmp, port_mmio + PORT_SCR_ERR);
++
++		/* ack any pending irq events for this port */
++		tmp = readl(port_mmio + PORT_IRQ_STAT);
++		VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
++		if (tmp)
++			writel(tmp, port_mmio + PORT_IRQ_STAT);
++
++		writel(1 << i, mmio + HOST_IRQ_STAT);
++
++		/* set irq mask (enables interrupts) */
++		writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
++	}
++
++	tmp = readl(mmio + HOST_CTL);
++	VPRINTK("HOST_CTL 0x%x\n", tmp);
++	writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
++	tmp = readl(mmio + HOST_CTL);
++	VPRINTK("HOST_CTL 0x%x\n", tmp);
++
++	pci_set_master(pdev);
++
++	return 0;
++}
++
++/* move to PCI layer, integrate w/ MSI stuff */
++static void pci_enable_intx(struct pci_dev *pdev)
++{
++	u16 pci_command;
++
++	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
++	if (pci_command & PCI_COMMAND_INTX_DISABLE) {
++		pci_command &= ~PCI_COMMAND_INTX_DISABLE;
++		pci_write_config_word(pdev, PCI_COMMAND, pci_command);
++	}
++}
++
++static void ahci_print_info(struct ata_probe_ent *probe_ent)
++{
++	struct ahci_host_priv *hpriv = probe_ent->private_data;
++	struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
++	void *mmio = probe_ent->mmio_base;
++	u32 vers, cap, impl, speed;
++	const char *speed_s;
++	u16 cc;
++	const char *scc_s;
++
++	vers = readl(mmio + HOST_VERSION);
++	cap = hpriv->cap;
++	impl = hpriv->port_map;
++
++	speed = (cap >> 20) & 0xf;
++	if (speed == 1)
++		speed_s = "1.5";
++	else if (speed == 2)
++		speed_s = "3";
++	else
++		speed_s = "?";
++
++	pci_read_config_word(pdev, 0x0a, &cc);
++	if (cc == 0x0101)
++		scc_s = "IDE";
++	else if (cc == 0x0106)
++		scc_s = "SATA";
++	else if (cc == 0x0104)
++		scc_s = "RAID";
++	else
++		scc_s = "unknown";
++
++	printk(KERN_INFO DRV_NAME "(%s) AHCI %02x%02x.%02x%02x "
++		"%u slots %u ports %s Gbps 0x%x impl %s mode\n"
++	       	,
++	       	pci_name(pdev),
++
++	       	(vers >> 24) & 0xff,
++	       	(vers >> 16) & 0xff,
++	       	(vers >> 8) & 0xff,
++	       	vers & 0xff,
++
++		((cap >> 8) & 0x1f) + 1,
++		(cap & 0x1f) + 1,
++		speed_s,
++		impl,
++		scc_s);
++
++	printk(KERN_INFO DRV_NAME "(%s) flags: "
++	       	"%s%s%s%s%s%s"
++	       	"%s%s%s%s%s%s%s\n"
++	       	,
++	       	pci_name(pdev),
++
++		cap & (1 << 31) ? "64bit " : "",
++		cap & (1 << 30) ? "ncq " : "",
++		cap & (1 << 28) ? "ilck " : "",
++		cap & (1 << 27) ? "stag " : "",
++		cap & (1 << 26) ? "pm " : "",
++		cap & (1 << 25) ? "led " : "",
++
++		cap & (1 << 24) ? "clo " : "",
++		cap & (1 << 19) ? "nz " : "",
++		cap & (1 << 18) ? "only " : "",
++		cap & (1 << 17) ? "pmp " : "",
++		cap & (1 << 15) ? "pio " : "",
++		cap & (1 << 14) ? "slum " : "",
++		cap & (1 << 13) ? "part " : ""
++		);
++}
++
++static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
++{
++	static int printed_version;
++	struct ata_probe_ent *probe_ent = NULL;
++	struct ahci_host_priv *hpriv;
++	unsigned long base;
++	void *mmio_base;
++	unsigned int board_idx = (unsigned int) ent->driver_data;
++	int rc;
++
++	VPRINTK("ENTER\n");
++
++	if (!printed_version++)
++		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
++
++	rc = pci_enable_device(pdev);
++	if (rc)
++		return rc;
++
++	rc = pci_request_regions(pdev, DRV_NAME);
++	if (rc)
++		goto err_out;
++
++	pci_enable_intx(pdev);
++
++	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
++	if (probe_ent == NULL) {
++		rc = -ENOMEM;
++		goto err_out_regions;
++	}
++
++	memset(probe_ent, 0, sizeof(*probe_ent));
++	probe_ent->dev = pci_dev_to_dev(pdev);
++	INIT_LIST_HEAD(&probe_ent->node);
++
++	mmio_base = ioremap(pci_resource_start(pdev, AHCI_PCI_BAR),
++		            pci_resource_len(pdev, AHCI_PCI_BAR));
++	if (mmio_base == NULL) {
++		rc = -ENOMEM;
++		goto err_out_free_ent;
++	}
++	base = (unsigned long) mmio_base;
++
++	hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
++	if (!hpriv) {
++		rc = -ENOMEM;
++		goto err_out_iounmap;
++	}
++	memset(hpriv, 0, sizeof(*hpriv));
++
++	probe_ent->sht		= ahci_port_info[board_idx].sht;
++	probe_ent->host_flags	= ahci_port_info[board_idx].host_flags;
++	probe_ent->pio_mask	= ahci_port_info[board_idx].pio_mask;
++	probe_ent->udma_mask	= ahci_port_info[board_idx].udma_mask;
++	probe_ent->port_ops	= ahci_port_info[board_idx].port_ops;
++
++       	probe_ent->irq = pdev->irq;
++       	probe_ent->irq_flags = SA_SHIRQ;
++	probe_ent->mmio_base = mmio_base;
++	probe_ent->private_data = hpriv;
++
++	/* initialize adapter */
++	rc = ahci_host_init(probe_ent);
++	if (rc)
++		goto err_out_hpriv;
++
++	ahci_print_info(probe_ent);
++
++	/* FIXME: check ata_device_add return value */
++	ata_device_add(probe_ent);
++	kfree(probe_ent);
++
++	return 0;
++
++err_out_hpriv:
++	kfree(hpriv);
++err_out_iounmap:
++	iounmap(mmio_base);
++err_out_free_ent:
++	kfree(probe_ent);
++err_out_regions:
++	pci_release_regions(pdev);
++err_out:
++	pci_disable_device(pdev);
++	return rc;
++}
++
++
++static int __init ahci_init(void)
++{
++	return pci_module_init(&ahci_pci_driver);
++}
++
++
++static void __exit ahci_exit(void)
++{
++	pci_unregister_driver(&ahci_pci_driver);
++}
++
++
++MODULE_AUTHOR("Jeff Garzik");
++MODULE_DESCRIPTION("AHCI SATA low-level driver");
++MODULE_LICENSE("GPL");
++MODULE_DEVICE_TABLE(pci, ahci_pci_tbl);
++
++module_init(ahci_init);
++module_exit(ahci_exit);
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/ata_piix.c kernel-source-2.6.8-2.6.8/drivers/scsi/ata_piix.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/ata_piix.c	2006-08-11 14:32:56.761745873 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/ata_piix.c	2006-08-11 14:32:25.430028523 -0600
+@@ -32,13 +32,14 @@
+ #include <linux/libata.h>
+ 
+ #define DRV_NAME	"ata_piix"
+-#define DRV_VERSION	"1.02"
++#define DRV_VERSION	"1.03"
+ 
+ enum {
+ 	PIIX_IOCFG		= 0x54, /* IDE I/O configuration register */
+ 	ICH5_PMR		= 0x90, /* port mapping register */
+ 	ICH5_PCS		= 0x92,	/* port control and status */
+ 
++	PIIX_FLAG_AHCI		= (1 << 28), /* AHCI possible */
+ 	PIIX_FLAG_CHECKINTR	= (1 << 29), /* make sure PCI INTx enabled */
+ 	PIIX_FLAG_COMBINED	= (1 << 30), /* combined mode possible */
+ 
+@@ -58,6 +59,7 @@
+ 	ich5_sata		= 1,
+ 	piix4_pata		= 2,
+ 	ich6_sata		= 3,
++	ich6_sata_rm		= 4,
+ };
+ 
+ static int piix_init_one (struct pci_dev *pdev,
+@@ -65,10 +67,8 @@
+ 
+ static void piix_pata_phy_reset(struct ata_port *ap);
+ static void piix_sata_phy_reset(struct ata_port *ap);
+-static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev,
+-			      unsigned int pio);
+-static void piix_set_udmamode (struct ata_port *ap, struct ata_device *adev,
+-			       unsigned int udma);
++static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
++static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
+ 
+ static unsigned int in_module_init = 1;
+ 
+@@ -87,13 +87,9 @@
+ 	{ 0x8086, 0x24df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
+ 	{ 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
+ 	{ 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
+-
+-	/* ICH6 operates in two modes, "looks-like-ICH5" mode,
+-	 * and enhanced mode, with queueing and other fancy stuff.
+-	 * This is distinguished by PCI class code.
+-	 */
+ 	{ 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
+-	{ 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
++	{ 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
++	{ 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
+ 
+ 	{ }	/* terminate list */
+ };
+@@ -108,6 +104,7 @@
+ static Scsi_Host_Template piix_sht = {
+ 	.module			= THIS_MODULE,
+ 	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
+ 	.queuecommand		= ata_scsi_queuecmd,
+ 	.eh_strategy_handler	= ata_scsi_error,
+ 	.can_queue		= ATA_DEF_QUEUE,
+@@ -126,17 +123,18 @@
+ static struct ata_port_operations piix_pata_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.set_piomode		= piix_set_piomode,
+-	.set_udmamode		= piix_set_udmamode,
++	.set_dmamode		= piix_set_dmamode,
+ 
+-	.tf_load		= ata_tf_load_pio,
+-	.tf_read		= ata_tf_read_pio,
+-	.check_status		= ata_check_status_pio,
+-	.exec_command		= ata_exec_command_pio,
++	.tf_load		= ata_tf_load,
++	.tf_read		= ata_tf_read,
++	.check_status		= ata_check_status,
++	.exec_command		= ata_exec_command,
++	.dev_select		= ata_std_dev_select,
+ 
+ 	.phy_reset		= piix_pata_phy_reset,
+ 
+-	.bmdma_setup		= ata_bmdma_setup_pio,
+-	.bmdma_start		= ata_bmdma_start_pio,
++	.bmdma_setup		= ata_bmdma_setup,
++	.bmdma_start		= ata_bmdma_start,
+ 	.qc_prep		= ata_qc_prep,
+ 	.qc_issue		= ata_qc_issue_prot,
+ 
+@@ -151,18 +149,17 @@
+ 
+ static struct ata_port_operations piix_sata_ops = {
+ 	.port_disable		= ata_port_disable,
+-	.set_piomode		= piix_set_piomode,
+-	.set_udmamode		= piix_set_udmamode,
+ 
+-	.tf_load		= ata_tf_load_pio,
+-	.tf_read		= ata_tf_read_pio,
+-	.check_status		= ata_check_status_pio,
+-	.exec_command		= ata_exec_command_pio,
++	.tf_load		= ata_tf_load,
++	.tf_read		= ata_tf_read,
++	.check_status		= ata_check_status,
++	.exec_command		= ata_exec_command,
++	.dev_select		= ata_std_dev_select,
+ 
+ 	.phy_reset		= piix_sata_phy_reset,
+ 
+-	.bmdma_setup		= ata_bmdma_setup_pio,
+-	.bmdma_start		= ata_bmdma_start_pio,
++	.bmdma_setup		= ata_bmdma_setup,
++	.bmdma_start		= ata_bmdma_start,
+ 	.qc_prep		= ata_qc_prep,
+ 	.qc_issue		= ata_qc_issue_prot,
+ 
+@@ -181,8 +178,13 @@
+ 		.sht		= &piix_sht,
+ 		.host_flags	= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
+ 				  PIIX_FLAG_CHECKINTR,
+-		.pio_mask	= 0x03,	/* pio3-4 */
+-		.udma_mask	= ATA_UDMA_MASK_40C, /* FIXME: cbl det */
++		.pio_mask	= 0x1f,	/* pio0-4 */
++#if 0
++		.mwdma_mask	= 0x06, /* mwdma1-2 */
++#else
++		.mwdma_mask	= 0x00, /* mwdma broken */
++#endif
++		.udma_mask	= 0x3f, /* udma0-5 */
+ 		.port_ops	= &piix_pata_ops,
+ 	},
+ 
+@@ -191,8 +193,9 @@
+ 		.sht		= &piix_sht,
+ 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
+ 				  PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR,
+-		.pio_mask	= 0x03,	/* pio3-4 */
+-		.udma_mask	= 0x7f,	/* udma0-6 ; FIXME */
++		.pio_mask	= 0x1f,	/* pio0-4 */
++		.mwdma_mask	= 0x07, /* mwdma0-2 */
++		.udma_mask	= 0x7f,	/* udma0-6 */
+ 		.port_ops	= &piix_sata_ops,
+ 	},
+ 
+@@ -200,8 +203,13 @@
+ 	{
+ 		.sht		= &piix_sht,
+ 		.host_flags	= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+-		.pio_mask	= 0x03, /* pio3-4 */
+-		.udma_mask	= ATA_UDMA_MASK_40C, /* FIXME: cbl det */
++		.pio_mask	= 0x1f,	/* pio0-4 */
++#if 0
++		.mwdma_mask	= 0x06, /* mwdma1-2 */
++#else
++		.mwdma_mask	= 0x00, /* mwdma broken */
++#endif
++		.udma_mask	= ATA_UDMA_MASK_40C,
+ 		.port_ops	= &piix_pata_ops,
+ 	},
+ 
+@@ -211,8 +219,21 @@
+ 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
+ 				  PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
+ 				  ATA_FLAG_SLAVE_POSS,
+-		.pio_mask	= 0x03,	/* pio3-4 */
+-		.udma_mask	= 0x7f,	/* udma0-6 ; FIXME */
++		.pio_mask	= 0x1f,	/* pio0-4 */
++		.mwdma_mask	= 0x07, /* mwdma0-2 */
++		.udma_mask	= 0x7f,	/* udma0-6 */
++		.port_ops	= &piix_sata_ops,
++	},
++
++	/* ich6_sata_rm */
++	{
++		.sht		= &piix_sht,
++		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
++				  PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
++				  ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
++		.pio_mask	= 0x1f,	/* pio0-4 */
++		.mwdma_mask	= 0x07, /* mwdma0-2 */
++		.udma_mask	= 0x7f,	/* udma0-6 */
+ 		.port_ops	= &piix_sata_ops,
+ 	},
+ };
+@@ -226,12 +247,13 @@
+ MODULE_DESCRIPTION("SCSI low-level driver for Intel PIIX/ICH ATA controllers");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
++MODULE_VERSION(DRV_VERSION);
+ 
+ /**
+  *	piix_pata_cbl_detect - Probe host controller cable detect info
+  *	@ap: Port for which cable detect info is desired
+  *
+- *	Read 80c cable indicator from SATA PCI device's PCI config
++ *	Read 80c cable indicator from ATA PCI device's PCI config
+  *	register.  This register is normally set by firmware (BIOS).
+  *
+  *	LOCKING:
+@@ -239,7 +261,7 @@
+  */
+ static void piix_pata_cbl_detect(struct ata_port *ap)
+ {
+-	struct pci_dev *pdev = ap->host_set->pdev;
++	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+ 	u8 tmp, mask;
+ 
+ 	/* no 80c support in host controller? */
+@@ -272,8 +294,9 @@
+ 
+ static void piix_pata_phy_reset(struct ata_port *ap)
+ {
+-	if (!pci_test_config_bits(ap->host_set->pdev,
+-				  &piix_enable_bits[ap->hard_port_no])) {
++	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
++
++	if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) {
+ 		ata_port_disable(ap);
+ 		printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
+ 		return;
+@@ -301,7 +324,7 @@
+  */
+ static int piix_sata_probe (struct ata_port *ap)
+ {
+-	struct pci_dev *pdev = ap->host_set->pdev;
++	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+ 	int combined = (ap->flags & ATA_FLAG_SLAVE_POSS);
+ 	int orig_mask, mask, i;
+ 	u8 pcs;
+@@ -368,11 +391,11 @@
+  *	None (inherited from caller).
+  */
+ 
+-static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev,
+-			      unsigned int pio)
++static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev)
+ {
+-	struct pci_dev *dev	= ap->host_set->pdev;
+-	unsigned int is_slave	= (adev->flags & ATA_DFLAG_MASTER) ? 0 : 1;
++	unsigned int pio	= adev->pio_mode - XFER_PIO_0;
++	struct pci_dev *dev	= to_pci_dev(ap->host_set->dev);
++	unsigned int is_slave	= (adev->devno != 0);
+ 	unsigned int master_port= ap->hard_port_no ? 0x42 : 0x40;
+ 	unsigned int slave_port	= 0x44;
+ 	u16 master_data;
+@@ -409,7 +432,7 @@
+ }
+ 
+ /**
+- *	piix_set_udmamode - Initialize host controller PATA PIO timings
++ *	piix_set_dmamode - Initialize host controller PATA PIO timings
+  *	@ap: Port whose timings we are configuring
+  *	@adev: um
+  *	@udma: udma mode, 0 - 6
+@@ -420,10 +443,10 @@
+  *	None (inherited from caller).
+  */
+ 
+-static void piix_set_udmamode (struct ata_port *ap, struct ata_device *adev,
+-			      unsigned int udma)
++static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev)
+ {
+-	struct pci_dev *dev	= ap->host_set->pdev;
++	unsigned int udma	= adev->dma_mode; /* FIXME: MWDMA too */
++	struct pci_dev *dev	= to_pci_dev(ap->host_set->dev);
+ 	u8 maslave		= ap->hard_port_no ? 0x42 : 0x40;
+ 	u8 speed		= udma;
+ 	unsigned int drive_dn	= (ap->hard_port_no ? 2 : 0) + adev->devno;
+@@ -452,25 +475,38 @@
+ 		case XFER_UDMA_3:
+ 		case XFER_UDMA_1:	u_speed = 1 << (drive_dn * 4); break;
+ 		case XFER_UDMA_0:	u_speed = 0 << (drive_dn * 4); break;
++		case XFER_MW_DMA_2:
++		case XFER_MW_DMA_1:	break;
+ 		default:
+ 			BUG();
+ 			return;
+ 	}
+ 
+-	if (!(reg48 & u_flag))
+-		pci_write_config_byte(dev, 0x48, reg48 | u_flag);
+-	if (speed == XFER_UDMA_5) {
+-		pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
++	if (speed >= XFER_UDMA_0) {
++		if (!(reg48 & u_flag))
++			pci_write_config_byte(dev, 0x48, reg48 | u_flag);
++		if (speed == XFER_UDMA_5) {
++			pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
++		} else {
++			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
++		}
++		if ((reg4a & a_speed) != u_speed)
++			pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
++		if (speed > XFER_UDMA_2) {
++			if (!(reg54 & v_flag))
++				pci_write_config_byte(dev, 0x54, reg54 | v_flag);
++		} else
++			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
+ 	} else {
+-		pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
++		if (reg48 & u_flag)
++			pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
++		if (reg4a & a_speed)
++			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
++		if (reg54 & v_flag)
++			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
++		if (reg55 & w_flag)
++			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
+ 	}
+-	if ((reg4a & a_speed) != u_speed)
+-		pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
+-	if (speed > XFER_UDMA_2) {
+-		if (!(reg54 & v_flag))
+-			pci_write_config_byte(dev, 0x54, reg54 | v_flag);
+-	} else
+-		pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
+ }
+ 
+ /* move to PCI layer, integrate w/ MSI stuff */
+@@ -485,6 +521,42 @@
+ 	}
+ }
+ 
++#define AHCI_PCI_BAR 5
++#define AHCI_GLOBAL_CTL 0x04
++#define AHCI_ENABLE (1 << 31)
++static int piix_disable_ahci(struct pci_dev *pdev)
++{
++	void *mmio;
++	unsigned long addr;
++	u32 tmp;
++	int rc = 0;
++
++	/* BUG: pci_enable_device has not yet been called.  This
++	 * works because this device is usually set up by BIOS.
++	 */
++
++	addr = pci_resource_start(pdev, AHCI_PCI_BAR);
++	if (!addr || !pci_resource_len(pdev, AHCI_PCI_BAR))
++		return 0;
++	
++	mmio = ioremap(addr, 64);
++	if (!mmio)
++		return -ENOMEM;
++	
++	tmp = readl(mmio + AHCI_GLOBAL_CTL);
++	if (tmp & AHCI_ENABLE) {
++		tmp &= ~AHCI_ENABLE;
++		writel(tmp, mmio + AHCI_GLOBAL_CTL);
++
++		tmp = readl(mmio + AHCI_GLOBAL_CTL);
++		if (tmp & AHCI_ENABLE)
++			rc = -EIO;
++	}
++	
++	iounmap(mmio);
++	return rc;
++}
++
+ /**
+  *	piix_init_one - Register PIIX ATA PCI device with kernel services
+  *	@pdev: PCI device to register
+@@ -517,6 +589,12 @@
+ 	port_info[0] = &piix_port_info[ent->driver_data];
+ 	port_info[1] = NULL;
+ 
++	if (port_info[0]->host_flags & PIIX_FLAG_AHCI) {
++		int rc = piix_disable_ahci(pdev);
++		if (rc)
++			return rc;
++	}
++
+ 	if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) {
+ 		u8 tmp;
+ 		pci_read_config_byte(pdev, ICH5_PMR, &tmp);
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/libata-core.c kernel-source-2.6.8-2.6.8/drivers/scsi/libata-core.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/libata-core.c	2006-08-11 14:32:56.764676171 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/libata-core.c	2006-08-11 14:32:25.404632611 -0600
+@@ -39,22 +39,27 @@
+ #include <linux/workqueue.h>
+ #include <scsi/scsi.h>
+ #include "scsi.h"
++#include "scsi_priv.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+ #include <asm/io.h>
+ #include <asm/semaphore.h>
++#include <asm/byteorder.h>
+ 
+ #include "libata.h"
+ 
+ static unsigned int ata_busy_sleep (struct ata_port *ap,
+ 				    unsigned long tmout_pat,
+ 			    	    unsigned long tmout);
+-static void __ata_dev_select (struct ata_port *ap, unsigned int device);
+-static void ata_host_set_pio(struct ata_port *ap);
+-static void ata_host_set_udma(struct ata_port *ap);
+-static void ata_dev_set_pio(struct ata_port *ap, unsigned int device);
+-static void ata_dev_set_udma(struct ata_port *ap, unsigned int device);
+ static void ata_set_mode(struct ata_port *ap);
++static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
++static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift);
++static int fgb(u32 bitmap);
++static int ata_choose_xfer_mode(struct ata_port *ap,
++				u8 *xfer_mode_out,
++				unsigned int *xfer_shift_out);
++static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
++static void __ata_qc_complete(struct ata_queued_cmd *qc);
+ 
+ static unsigned int ata_unique_id = 1;
+ static struct workqueue_struct *ata_wq;
+@@ -62,19 +67,20 @@
+ MODULE_AUTHOR("Jeff Garzik");
+ MODULE_DESCRIPTION("Library module for ATA devices");
+ MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_VERSION);
+ 
+ /**
+- *	ata_tf_load_pio - send taskfile registers to host controller
++ *	ata_tf_load - send taskfile registers to host controller
+  *	@ap: Port to which output is sent
+  *	@tf: ATA taskfile register set
+  *
+- *	Outputs ATA taskfile to standard ATA host controller using PIO.
++ *	Outputs ATA taskfile to standard ATA host controller.
+  *
+  *	LOCKING:
+  *	Inherited from caller.
+  */
+ 
+-void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
++static void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+@@ -132,7 +138,7 @@
+  *	Inherited from caller.
+  */
+ 
+-void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
++static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+@@ -179,19 +185,27 @@
+ 	ata_wait_idle(ap);
+ }
+ 
++void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
++{
++	if (ap->flags & ATA_FLAG_MMIO)
++		ata_tf_load_mmio(ap, tf);
++	else
++		ata_tf_load_pio(ap, tf);
++}
++
+ /**
+- *	ata_exec_command_pio - issue ATA command to host controller
++ *	ata_exec_command - issue ATA command to host controller
+  *	@ap: port to which command is being issued
+  *	@tf: ATA taskfile register set
+  *
+- *	Issues PIO write to ATA command register, with proper
++ *	Issues PIO/MMIO write to ATA command register, with proper
+  *	synchronization with interrupt handler / other threads.
+  *
+  *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf)
++static void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+ 	DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
+ 
+@@ -212,7 +226,7 @@
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
++static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+ 	DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
+ 
+@@ -220,12 +234,20 @@
+ 	ata_pause(ap);
+ }
+ 
++void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
++{
++	if (ap->flags & ATA_FLAG_MMIO)
++		ata_exec_command_mmio(ap, tf);
++	else
++		ata_exec_command_pio(ap, tf);
++}
++
+ /**
+  *	ata_exec - issue ATA command to host controller
+  *	@ap: port to which command is being issued
+  *	@tf: ATA taskfile register set
+  *
+- *	Issues PIO write to ATA command register, with proper
++ *	Issues PIO/MMIO write to ATA command register, with proper
+  *	synchronization with interrupt handler / other threads.
+  *
+  *	LOCKING:
+@@ -248,7 +270,7 @@
+  *	@tf: ATA taskfile register set
+  *
+  *	Issues ATA taskfile register set to ATA host controller,
+- *	via PIO, with proper synchronization with interrupt handler and
++ *	with proper synchronization with interrupt handler and
+  *	other threads.
+  *
+  *	LOCKING:
+@@ -268,7 +290,7 @@
+  *	@tf: ATA taskfile register set
+  *
+  *	Issues ATA taskfile register set to ATA host controller,
+- *	via PIO, with proper synchronization with interrupt handler and
++ *	with proper synchronization with interrupt handler and
+  *	other threads.
+  *
+  *	LOCKING:
+@@ -282,18 +304,18 @@
+ }
+ 
+ /**
+- *	ata_tf_read_pio - input device's ATA taskfile shadow registers
++ *	ata_tf_read - input device's ATA taskfile shadow registers
+  *	@ap: Port from which input is read
+  *	@tf: ATA taskfile register set for storing input
+  *
+  *	Reads ATA taskfile registers for currently-selected device
+- *	into @tf via PIO.
++ *	into @tf.
+  *
+  *	LOCKING:
+  *	Inherited from caller.
+  */
+ 
+-void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
++static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 
+@@ -325,7 +347,7 @@
+  *	Inherited from caller.
+  */
+ 
+-void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
++static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 
+@@ -345,18 +367,26 @@
+ 	}
+ }
+ 
++void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
++{
++	if (ap->flags & ATA_FLAG_MMIO)
++		ata_tf_read_mmio(ap, tf);
++	else
++		ata_tf_read_pio(ap, tf);
++}
++
+ /**
+- *	ata_check_status_pio - Read device status reg & clear interrupt
++ *	ata_check_status - Read device status reg & clear interrupt
+  *	@ap: port where the device is
+  *
+  *	Reads ATA taskfile status register for currently-selected device
+- *	via PIO and return it's value. This also clears pending interrupts
++ *	and return it's value. This also clears pending interrupts
+  *      from this device
+  *
+  *	LOCKING:
+  *	Inherited from caller.
+  */
+-u8 ata_check_status_pio(struct ata_port *ap)
++static u8 ata_check_status_pio(struct ata_port *ap)
+ {
+ 	return inb(ap->ioaddr.status_addr);
+ }
+@@ -372,11 +402,18 @@
+  *	LOCKING:
+  *	Inherited from caller.
+  */
+-u8 ata_check_status_mmio(struct ata_port *ap)
++static u8 ata_check_status_mmio(struct ata_port *ap)
+ {
+        	return readb((void *) ap->ioaddr.status_addr);
+ }
+ 
++u8 ata_check_status(struct ata_port *ap)
++{
++	if (ap->flags & ATA_FLAG_MMIO)
++		return ata_check_status_mmio(ap);
++	return ata_check_status_pio(ap);
++}
++
+ /**
+  *	ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
+  *	@tf: Taskfile to convert
+@@ -524,7 +561,7 @@
+ 	dev->write_cmd = (cmd >> 8) & 0xff;
+ }
+ 
+-static const char * udma_str[] = {
++static const char * xfer_mode_str[] = {
+ 	"UDMA/16",
+ 	"UDMA/25",
+ 	"UDMA/33",
+@@ -533,11 +570,19 @@
+ 	"UDMA/100",
+ 	"UDMA/133",
+ 	"UDMA7",
++	"MWDMA0",
++	"MWDMA1",
++	"MWDMA2",
++	"PIO0",
++	"PIO1",
++	"PIO2",
++	"PIO3",
++	"PIO4",
+ };
+ 
+ /**
+  *	ata_udma_string - convert UDMA bit offset to string
+- *	@udma_mask: mask of bits supported; only highest bit counts.
++ *	@mask: mask of bits supported; only highest bit counts.
+  *
+  *	Determine string which represents the highest speed
+  *	(highest bit in @udma_mask).
+@@ -550,16 +595,24 @@
+  *	@udma_mask, or the constant C string "<n/a>".
+  */
+ 
+-static const char *ata_udma_string(unsigned int udma_mask)
++static const char *ata_mode_string(unsigned int mask)
+ {
+ 	int i;
+ 
+-	for (i = 7; i >= 0; i--) {
+-		if (udma_mask & (1 << i))
+-			return udma_str[i];
+-	}
++	for (i = 7; i >= 0; i--)
++		if (mask & (1 << i))
++			goto out;
++	for (i = ATA_SHIFT_MWDMA + 2; i >= ATA_SHIFT_MWDMA; i--)
++		if (mask & (1 << i))
++			goto out;
++	for (i = ATA_SHIFT_PIO + 4; i >= ATA_SHIFT_PIO; i--)
++		if (mask & (1 << i))
++			goto out;
+ 
+ 	return "<n/a>";
++
++out:
++	return xfer_mode_str[i];
+ }
+ 
+ /**
+@@ -586,7 +639,7 @@
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 	u8 nsect, lbal;
+ 
+-	__ata_dev_select(ap, device);
++	ap->ops->dev_select(ap, device);
+ 
+ 	outb(0x55, ioaddr->nsect_addr);
+ 	outb(0xaa, ioaddr->lbal_addr);
+@@ -630,7 +683,7 @@
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 	u8 nsect, lbal;
+ 
+-	__ata_dev_select(ap, device);
++	ap->ops->dev_select(ap, device);
+ 
+ 	writeb(0x55, (void *) ioaddr->nsect_addr);
+ 	writeb(0xaa, (void *) ioaddr->lbal_addr);
+@@ -651,7 +704,7 @@
+ }
+ 
+ /**
+- *	ata_dev_devchk - PATA device presence detection
++ *	ata_devchk - PATA device presence detection
+  *	@ap: ATA channel to examine
+  *	@device: Device to examine (starting at zero)
+  *
+@@ -663,7 +716,7 @@
+  *	caller.
+  */
+ 
+-static unsigned int ata_dev_devchk(struct ata_port *ap,
++static unsigned int ata_devchk(struct ata_port *ap,
+ 				    unsigned int device)
+ {
+ 	if (ap->flags & ATA_FLAG_MMIO)
+@@ -687,7 +740,7 @@
+  *	the event of failure.
+  */
+ 
+-static unsigned int ata_dev_classify(struct ata_taskfile *tf)
++unsigned int ata_dev_classify(struct ata_taskfile *tf)
+ {
+ 	/* Apple's open source Darwin code hints that some devices only
+ 	 * put a proper signature into the LBA mid/high registers,
+@@ -735,7 +788,7 @@
+ 	unsigned int class;
+ 	u8 err;
+ 
+-	__ata_dev_select(ap, device);
++	ap->ops->dev_select(ap, device);
+ 
+ 	memset(&tf, 0, sizeof(tf));
+ 
+@@ -766,7 +819,7 @@
+ 
+ /**
+  *	ata_dev_id_string - Convert IDENTIFY DEVICE page into string
+- *	@dev: Device whose IDENTIFY DEVICE results we will examine
++ *	@id: IDENTIFY DEVICE results we will examine
+  *	@s: string into which data is output
+  *	@ofs: offset into identify device page
+  *	@len: length of string to return. must be an even number.
+@@ -779,17 +832,17 @@
+  *	caller.
+  */
+ 
+-void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
++void ata_dev_id_string(u16 *id, unsigned char *s,
+ 		       unsigned int ofs, unsigned int len)
+ {
+ 	unsigned int c;
+ 
+ 	while (len > 0) {
+-		c = dev->id[ofs] >> 8;
++		c = id[ofs] >> 8;
+ 		*s = c;
+ 		s++;
+ 
+-		c = dev->id[ofs] & 0xff;
++		c = id[ofs] & 0xff;
+ 		*s = c;
+ 		s++;
+ 
+@@ -798,8 +851,12 @@
+ 	}
+ }
+ 
++void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
++{
++}
++
+ /**
+- *	__ata_dev_select - Select device 0/1 on ATA bus
++ *	ata_std_dev_select - Select device 0/1 on ATA bus
+  *	@ap: ATA channel to manipulate
+  *	@device: ATA device (numbered from zero) to select
+  *
+@@ -811,7 +868,7 @@
+  *	caller.
+  */
+ 
+-static void __ata_dev_select (struct ata_port *ap, unsigned int device)
++void ata_std_dev_select (struct ata_port *ap, unsigned int device)
+ {
+ 	u8 tmp;
+ 
+@@ -839,7 +896,7 @@
+  *	make either device 0, or device 1, active on the
+  *	ATA channel.
+  *
+- *	This is a high-level version of __ata_dev_select(),
++ *	This is a high-level version of ata_std_dev_select(),
+  *	which additionally provides the services of inserting
+  *	the proper pauses and status polling, where needed.
+  *
+@@ -856,7 +913,7 @@
+ 	if (wait)
+ 		ata_wait_idle(ap);
+ 
+-	__ata_dev_select(ap, device);
++	ap->ops->dev_select(ap, device);
+ 
+ 	if (wait) {
+ 		if (can_sleep && ap->device[device].class == ATA_DEV_ATAPI)
+@@ -930,10 +987,14 @@
+ {
+ 	struct ata_device *dev = &ap->device[device];
+ 	unsigned int i;
+-	u16 tmp, udma_modes;
++	u16 tmp;
++	unsigned long xfer_modes;
+ 	u8 status;
+-	struct ata_taskfile tf;
+ 	unsigned int using_edd;
++	DECLARE_COMPLETION(wait);
++	struct ata_queued_cmd *qc;
++	unsigned long flags;
++	int rc;
+ 
+ 	if (!ata_dev_present(dev)) {
+ 		DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n",
+@@ -953,27 +1014,34 @@
+ 
+ 	ata_dev_select(ap, device, 1, 1); /* select device 0/1 */
+ 
+-retry:
+-	ata_tf_init(ap, &tf, device);
+-	tf.ctl |= ATA_NIEN;
+-	tf.protocol = ATA_PROT_PIO;
++	qc = ata_qc_new_init(ap, dev);
++	BUG_ON(qc == NULL);
++
++	ata_sg_init_one(qc, dev->id, sizeof(dev->id));
++	qc->dma_dir = DMA_FROM_DEVICE;
++	qc->tf.protocol = ATA_PROT_PIO;
++	qc->nsect = 1;
+ 
++retry:
+ 	if (dev->class == ATA_DEV_ATA) {
+-		tf.command = ATA_CMD_ID_ATA;
++		qc->tf.command = ATA_CMD_ID_ATA;
+ 		DPRINTK("do ATA identify\n");
+ 	} else {
+-		tf.command = ATA_CMD_ID_ATAPI;
++		qc->tf.command = ATA_CMD_ID_ATAPI;
+ 		DPRINTK("do ATAPI identify\n");
+ 	}
+ 
+-	ata_tf_to_host(ap, &tf);
++	qc->waiting = &wait;
++	qc->complete_fn = ata_qc_complete_noop;
+ 
+-	/* crazy ATAPI devices... */
+-	if (dev->class == ATA_DEV_ATAPI)
+-		msleep(150);
++	spin_lock_irqsave(&ap->host_set->lock, flags);
++	rc = ata_qc_issue(qc);
++	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+ 
+-	if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT))
++	if (rc)
+ 		goto err_out;
++	else
++		wait_for_completion(&wait);
+ 
+ 	status = ata_chk_status(ap);
+ 	if (status & ATA_ERR) {
+@@ -988,44 +1056,21 @@
+ 		 * ATA software reset (SRST, the default) does not appear
+ 		 * to have this problem.
+ 		 */
+-		if ((using_edd) && (tf.command == ATA_CMD_ID_ATA)) {
++		if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) {
+ 			u8 err = ata_chk_err(ap);
+ 			if (err & ATA_ABORTED) {
+ 				dev->class = ATA_DEV_ATAPI;
++				qc->cursg = 0;
++				qc->cursg_ofs = 0;
++				qc->cursect = 0;
++				qc->nsect = 1;
+ 				goto retry;
+ 			}
+ 		}
+ 		goto err_out;
+ 	}
+ 
+-	/* make sure we have BSY=0, DRQ=1 */
+-	if ((status & ATA_DRQ) == 0) {
+-		printk(KERN_WARNING "ata%u: dev %u (ATA%s?) not returning id page (0x%x)\n",
+-		       ap->id, device,
+-		       dev->class == ATA_DEV_ATA ? "" : "PI",
+-		       status);
+-		goto err_out;
+-	}
+-
+-	/* read IDENTIFY [X] DEVICE page */
+-	if (ap->flags & ATA_FLAG_MMIO) {
+-		for (i = 0; i < ATA_ID_WORDS; i++)
+-			dev->id[i] = readw((void *)ap->ioaddr.data_addr);
+-	} else
+-		for (i = 0; i < ATA_ID_WORDS; i++)
+-			dev->id[i] = inw(ap->ioaddr.data_addr);
+-
+-	/* wait for host_idle */
+-	status = ata_wait_idle(ap);
+-	if (status & (ATA_BUSY | ATA_DRQ)) {
+-		printk(KERN_WARNING "ata%u: dev %u (ATA%s?) error after id page (0x%x)\n",
+-		       ap->id, device,
+-		       dev->class == ATA_DEV_ATA ? "" : "PI",
+-		       status);
+-		goto err_out;
+-	}
+-
+-	ata_irq_on(ap);	/* re-enable interrupts */
++	swap_buf_le16(dev->id, ATA_ID_WORDS);
+ 
+ 	/* print device capabilities */
+ 	printk(KERN_DEBUG "ata%u: dev %u cfg "
+@@ -1040,24 +1085,25 @@
+ 	 */
+ 
+ 	/* we require LBA and DMA support (bits 8 & 9 of word 49) */
+-	if (!ata_id_has_dma(dev) || !ata_id_has_lba(dev)) {
++	if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) {
+ 		printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id);
+ 		goto err_out_nosup;
+ 	}
+ 
+-	/* we require UDMA support */
+-	udma_modes =
+-	tmp = dev->id[ATA_ID_UDMA_MODES];
+-	if ((tmp & 0xff) == 0) {
+-		printk(KERN_DEBUG "ata%u: no udma\n", ap->id);
+-		goto err_out_nosup;
++	/* quick-n-dirty find max transfer mode; for printk only */
++	xfer_modes = dev->id[ATA_ID_UDMA_MODES];
++	if (!xfer_modes)
++		xfer_modes = (dev->id[ATA_ID_MWDMA_MODES]) << ATA_SHIFT_MWDMA;
++	if (!xfer_modes) {
++		xfer_modes = (dev->id[ATA_ID_PIO_MODES]) << (ATA_SHIFT_PIO + 3);
++		xfer_modes |= (0x7 << ATA_SHIFT_PIO);
+ 	}
+ 
+ 	ata_dump_id(dev);
+ 
+ 	/* ATA-specific feature tests */
+ 	if (dev->class == ATA_DEV_ATA) {
+-		if (!ata_id_is_ata(dev))	/* sanity check */
++		if (!ata_id_is_ata(dev->id))	/* sanity check */
+ 			goto err_out_nosup;
+ 
+ 		tmp = dev->id[ATA_ID_MAJOR_VER];
+@@ -1071,11 +1117,11 @@
+ 			goto err_out_nosup;
+ 		}
+ 
+-		if (ata_id_has_lba48(dev)) {
++		if (ata_id_has_lba48(dev->id)) {
+ 			dev->flags |= ATA_DFLAG_LBA48;
+-			dev->n_sectors = ata_id_u64(dev, 100);
++			dev->n_sectors = ata_id_u64(dev->id, 100);
+ 		} else {
+-			dev->n_sectors = ata_id_u32(dev, 60);
++			dev->n_sectors = ata_id_u32(dev->id, 60);
+ 		}
+ 
+ 		ap->host->max_cmd_len = 16;
+@@ -1083,25 +1129,28 @@
+ 		/* print device info to dmesg */
+ 		printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n",
+ 		       ap->id, device,
+-		       ata_udma_string(udma_modes),
++		       ata_mode_string(xfer_modes),
+ 		       (unsigned long long)dev->n_sectors,
+ 		       dev->flags & ATA_DFLAG_LBA48 ? " lba48" : "");
+ 	}
+ 
+ 	/* ATAPI-specific feature tests */
+ 	else {
+-		if (ata_id_is_ata(dev))		/* sanity check */
++		if (ata_id_is_ata(dev->id))		/* sanity check */
+ 			goto err_out_nosup;
+ 
+-		/* see if 16-byte commands supported */
+-		tmp = dev->id[0] & 0x3;
+-		if (tmp == 1)
+-			ap->host->max_cmd_len = 16;
++		rc = atapi_cdb_len(dev->id);
++		if ((rc < 12) || (rc > ATAPI_CDB_LEN)) {
++			printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id);
++			goto err_out_nosup;
++		}
++		ap->cdb_len = (unsigned int) rc;
++		ap->host->max_cmd_len = (unsigned char) ap->cdb_len;
+ 
+ 		/* print device info to dmesg */
+ 		printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
+ 		       ap->id, device,
+-		       ata_udma_string(udma_modes));
++		       ata_mode_string(xfer_modes));
+ 	}
+ 
+ 	DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap));
+@@ -1171,13 +1220,13 @@
+ }
+ 
+ /**
+- *	sata_phy_reset -
++ *	__sata_phy_reset -
+  *	@ap:
+  *
+  *	LOCKING:
+  *
+  */
+-void sata_phy_reset(struct ata_port *ap)
++void __sata_phy_reset(struct ata_port *ap)
+ {
+ 	u32 sstatus;
+ 	unsigned long timeout = jiffies + (HZ * 5);
+@@ -1215,6 +1264,21 @@
+ 		return;
+ 	}
+ 
++	ap->cbl = ATA_CBL_SATA;
++}
++
++/**
++ *	__sata_phy_reset -
++ *	@ap:
++ *
++ *	LOCKING:
++ *
++ */
++void sata_phy_reset(struct ata_port *ap)
++{
++	__sata_phy_reset(ap);
++	if (ap->flags & ATA_FLAG_PORT_DISABLED)
++		return;
+ 	ata_bus_reset(ap);
+ }
+ 
+@@ -1232,6 +1296,101 @@
+ 	ap->flags |= ATA_FLAG_PORT_DISABLED;
+ }
+ 
++static struct {
++	unsigned int shift;
++	u8 base;
++} xfer_mode_classes[] = {
++	{ ATA_SHIFT_UDMA,	XFER_UDMA_0 },
++	{ ATA_SHIFT_MWDMA,	XFER_MW_DMA_0 },
++	{ ATA_SHIFT_PIO,	XFER_PIO_0 },
++};
++
++static inline u8 base_from_shift(unsigned int shift)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++)
++		if (xfer_mode_classes[i].shift == shift)
++			return xfer_mode_classes[i].base;
++
++	return 0xff;
++}
++
++static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
++{
++	int ofs, idx;
++	u8 base;
++
++	if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
++		return;
++
++	if (dev->xfer_shift == ATA_SHIFT_PIO)
++		dev->flags |= ATA_DFLAG_PIO;
++
++	ata_dev_set_xfermode(ap, dev);
++
++	base = base_from_shift(dev->xfer_shift);
++	ofs = dev->xfer_mode - base;
++	idx = ofs + dev->xfer_shift;
++	WARN_ON(idx >= ARRAY_SIZE(xfer_mode_str));
++
++	DPRINTK("idx=%d xfer_shift=%u, xfer_mode=0x%x, base=0x%x, offset=%d\n",
++		idx, dev->xfer_shift, (int)dev->xfer_mode, (int)base, ofs);
++
++	printk(KERN_INFO "ata%u: dev %u configured for %s\n",
++		ap->id, dev->devno, xfer_mode_str[idx]);
++}
++
++static int ata_host_set_pio(struct ata_port *ap)
++{
++	unsigned int mask;
++	int x, i;
++	u8 base, xfer_mode;
++
++	mask = ata_get_mode_mask(ap, ATA_SHIFT_PIO);
++	x = fgb(mask);
++	if (x < 0) {
++		printk(KERN_WARNING "ata%u: no PIO support\n", ap->id);
++		return -1;
++	}
++
++	base = base_from_shift(ATA_SHIFT_PIO);
++	xfer_mode = base + x;
++
++	DPRINTK("base 0x%x xfer_mode 0x%x mask 0x%x x %d\n",
++		(int)base, (int)xfer_mode, mask, x);
++
++	for (i = 0; i < ATA_MAX_DEVICES; i++) {
++		struct ata_device *dev = &ap->device[i];
++		if (ata_dev_present(dev)) {
++			dev->pio_mode = xfer_mode;
++			dev->xfer_mode = xfer_mode;
++			dev->xfer_shift = ATA_SHIFT_PIO;
++			if (ap->ops->set_piomode)
++				ap->ops->set_piomode(ap, dev);
++		}
++	}
++
++	return 0;
++}
++
++static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
++			    unsigned int xfer_shift)
++{
++	int i;
++
++	for (i = 0; i < ATA_MAX_DEVICES; i++) {
++		struct ata_device *dev = &ap->device[i];
++		if (ata_dev_present(dev)) {
++			dev->dma_mode = xfer_mode;
++			dev->xfer_mode = xfer_mode;
++			dev->xfer_shift = xfer_shift;
++			if (ap->ops->set_dmamode)
++				ap->ops->set_dmamode(ap, dev);
++		}
++	}
++}
++
+ /**
+  *	ata_set_mode - Program timings and issue SET FEATURES - XFER
+  *	@ap: port on which timings will be programmed
+@@ -1241,29 +1400,28 @@
+  */
+ static void ata_set_mode(struct ata_port *ap)
+ {
+-	unsigned int force_pio, i;
+-
+-	ata_host_set_pio(ap);
+-	if (ap->flags & ATA_FLAG_PORT_DISABLED)
+-		return;
++	unsigned int i, xfer_shift;
++	u8 xfer_mode;
++	int rc;
+ 
+-	ata_host_set_udma(ap);
+-	if (ap->flags & ATA_FLAG_PORT_DISABLED)
+-		return;
++	/* step 1: always set host PIO timings */
++	rc = ata_host_set_pio(ap);
++	if (rc)
++		goto err_out;
+ 
+-#ifdef ATA_FORCE_PIO
+-	force_pio = 1;
+-#else
+-	force_pio = 0;
+-#endif
++	/* step 2: choose the best data xfer mode */
++	xfer_mode = xfer_shift = 0;
++	rc = ata_choose_xfer_mode(ap, &xfer_mode, &xfer_shift);
++	if (rc)
++		goto err_out;
+ 
+-	if (force_pio) {
+-		ata_dev_set_pio(ap, 0);
+-		ata_dev_set_pio(ap, 1);
+-	} else {
+-		ata_dev_set_udma(ap, 0);
+-		ata_dev_set_udma(ap, 1);
+-	}
++	/* step 3: if that xfer mode isn't PIO, set host DMA timings */
++	if (xfer_shift != ATA_SHIFT_PIO)
++		ata_host_set_dma(ap, xfer_mode, xfer_shift);
++
++	/* step 4: update devices' xfer mode */
++	ata_dev_set_mode(ap, &ap->device[0]);
++	ata_dev_set_mode(ap, &ap->device[1]);
+ 
+ 	if (ap->flags & ATA_FLAG_PORT_DISABLED)
+ 		return;
+@@ -1275,6 +1433,11 @@
+ 		struct ata_device *dev = &ap->device[i];
+ 		ata_dev_set_protocol(dev);
+ 	}
++
++	return;
++
++err_out:
++	ata_port_disable(ap);
+ }
+ 
+ /**
+@@ -1328,20 +1491,20 @@
+ 	unsigned int dev1 = devmask & (1 << 1);
+ 	unsigned long timeout;
+ 
+-	/* if device 0 was found in ata_dev_devchk, wait for its
++	/* if device 0 was found in ata_devchk, wait for its
+ 	 * BSY bit to clear
+ 	 */
+ 	if (dev0)
+ 		ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ 
+-	/* if device 1 was found in ata_dev_devchk, wait for
++	/* if device 1 was found in ata_devchk, wait for
+ 	 * register access, then wait for BSY to clear
+ 	 */
+ 	timeout = jiffies + ATA_TMOUT_BOOT;
+ 	while (dev1) {
+ 		u8 nsect, lbal;
+ 
+-		__ata_dev_select(ap, 1);
++		ap->ops->dev_select(ap, 1);
+ 		if (ap->flags & ATA_FLAG_MMIO) {
+ 			nsect = readb((void *) ioaddr->nsect_addr);
+ 			lbal = readb((void *) ioaddr->lbal_addr);
+@@ -1361,11 +1524,11 @@
+ 		ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ 
+ 	/* is all this really necessary? */
+-	__ata_dev_select(ap, 0);
++	ap->ops->dev_select(ap, 0);
+ 	if (dev1)
+-		__ata_dev_select(ap, 1);
++		ap->ops->dev_select(ap, 1);
+ 	if (dev0)
+-		__ata_dev_select(ap, 0);
++		ap->ops->dev_select(ap, 0);
+ }
+ 
+ /**
+@@ -1469,9 +1632,9 @@
+ 	if (ap->flags & ATA_FLAG_SATA_RESET)
+ 		dev0 = 1;
+ 	else {
+-		dev0 = ata_dev_devchk(ap, 0);
++		dev0 = ata_devchk(ap, 0);
+ 		if (slave_possible)
+-			dev1 = ata_dev_devchk(ap, 1);
++			dev1 = ata_devchk(ap, 1);
+ 	}
+ 
+ 	if (dev0)
+@@ -1480,7 +1643,7 @@
+ 		devmask |= (1 << 1);
+ 
+ 	/* select device 0 again */
+-	__ata_dev_select(ap, 0);
++	ap->ops->dev_select(ap, 0);
+ 
+ 	/* issue bus reset */
+ 	if (ap->flags & ATA_FLAG_SRST)
+@@ -1509,9 +1672,9 @@
+ 
+ 	/* is double-select really necessary? */
+ 	if (ap->device[1].class != ATA_DEV_NONE)
+-		__ata_dev_select(ap, 1);
++		ap->ops->dev_select(ap, 1);
+ 	if (ap->device[0].class != ATA_DEV_NONE)
+-		__ata_dev_select(ap, 0);
++		ap->ops->dev_select(ap, 0);
+ 
+ 	/* if no devices were detected, disable this port */
+ 	if ((ap->device[0].class == ATA_DEV_NONE) &&
+@@ -1536,116 +1699,104 @@
+ 	DPRINTK("EXIT\n");
+ }
+ 
+-/**
+- *	ata_host_set_pio -
+- *	@ap:
+- *
+- *	LOCKING:
+- */
+-
+-static void ata_host_set_pio(struct ata_port *ap)
++static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
+ {
+ 	struct ata_device *master, *slave;
+-	unsigned int pio, i;
+-	u16 mask;
++	unsigned int mask;
+ 
+ 	master = &ap->device[0];
+ 	slave = &ap->device[1];
+ 
+ 	assert (ata_dev_present(master) || ata_dev_present(slave));
+ 
+-	mask = ap->pio_mask;
+-	if (ata_dev_present(master))
+-		mask &= (master->id[ATA_ID_PIO_MODES] & 0x03);
+-	if (ata_dev_present(slave))
+-		mask &= (slave->id[ATA_ID_PIO_MODES] & 0x03);
+-
+-	/* require pio mode 3 or 4 support for host and all devices */
+-	if (mask == 0) {
+-		printk(KERN_WARNING "ata%u: no PIO3/4 support, ignoring\n",
+-		       ap->id);
+-		goto err_out;
++	if (shift == ATA_SHIFT_UDMA) {
++		mask = ap->udma_mask;
++		if (ata_dev_present(master))
++			mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
++		if (ata_dev_present(slave))
++			mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
++	}
++	else if (shift == ATA_SHIFT_MWDMA) {
++		mask = ap->mwdma_mask;
++		if (ata_dev_present(master))
++			mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07);
++		if (ata_dev_present(slave))
++			mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07);
++	}
++	else if (shift == ATA_SHIFT_PIO) {
++		mask = ap->pio_mask;
++		if (ata_dev_present(master)) {
++			/* spec doesn't return explicit support for
++			 * PIO0-2, so we fake it
++			 */
++			u16 tmp_mode = master->id[ATA_ID_PIO_MODES] & 0x03;
++			tmp_mode <<= 3;
++			tmp_mode |= 0x7;
++			mask &= tmp_mode;
++		}
++		if (ata_dev_present(slave)) {
++			/* spec doesn't return explicit support for
++			 * PIO0-2, so we fake it
++			 */
++			u16 tmp_mode = slave->id[ATA_ID_PIO_MODES] & 0x03;
++			tmp_mode <<= 3;
++			tmp_mode |= 0x7;
++			mask &= tmp_mode;
++		}
++	}
++	else {
++		mask = 0xffffffff; /* shut up compiler warning */
++		BUG();
+ 	}
+ 
+-	pio = (mask & ATA_ID_PIO4) ? 4 : 3;
+-	for (i = 0; i < ATA_MAX_DEVICES; i++)
+-		if (ata_dev_present(&ap->device[i])) {
+-			ap->device[i].pio_mode = (pio == 3) ?
+-				XFER_PIO_3 : XFER_PIO_4;
+-			if (ap->ops->set_piomode)
+-				ap->ops->set_piomode(ap, &ap->device[i], pio);
+-		}
++	return mask;
++}
+ 
+-	return;
++/* find greatest bit */
++static int fgb(u32 bitmap)
++{
++	unsigned int i;
++	int x = -1;
+ 
+-err_out:
+-	ap->ops->port_disable(ap);
++	for (i = 0; i < 32; i++)
++		if (bitmap & (1 << i))
++			x = i;
++
++	return x;
+ }
+ 
+ /**
+- *	ata_host_set_udma -
+- *	@ap:
++ *	ata_choose_xfer_mode - attempt to find best transfer mode
++ *	@ap: Port for which an xfer mode will be selected
++ *	@xfer_mode_out: (output) SET FEATURES - XFER MODE code
++ *	@xfer_shift_out: (output) bit shift that selects this mode
+  *
+  *	LOCKING:
++ *
++ *	RETURNS:
++ *	Zero on success, negative on error.
+  */
+ 
+-static void ata_host_set_udma(struct ata_port *ap)
+-{
+-	struct ata_device *master, *slave;
+-	u16 mask;
+-	unsigned int i, j;
+-	int udma_mode = -1;
+-
+-	master = &ap->device[0];
+-	slave = &ap->device[1];
+-
+-	assert (ata_dev_present(master) || ata_dev_present(slave));
+-	assert ((ap->flags & ATA_FLAG_PORT_DISABLED) == 0);
+-
+-	DPRINTK("udma masks: host 0x%X, master 0x%X, slave 0x%X\n",
+-		ap->udma_mask,
+-		(!ata_dev_present(master)) ? 0xff :
+-			(master->id[ATA_ID_UDMA_MODES] & 0xff),
+-		(!ata_dev_present(slave)) ? 0xff :
+-			(slave->id[ATA_ID_UDMA_MODES] & 0xff));
+-
+-	mask = ap->udma_mask;
+-	if (ata_dev_present(master))
+-		mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
+-	if (ata_dev_present(slave))
+-		mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
+-
+-	i = XFER_UDMA_7;
+-	while (i >= XFER_UDMA_0) {
+-		j = i - XFER_UDMA_0;
+-		DPRINTK("mask 0x%X i 0x%X j %u\n", mask, i, j);
+-		if (mask & (1 << j)) {
+-			udma_mode = i;
+-			break;
++static int ata_choose_xfer_mode(struct ata_port *ap,
++				u8 *xfer_mode_out,
++				unsigned int *xfer_shift_out)
++{
++	unsigned int mask, shift;
++	int x, i;
++
++	for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) {
++		shift = xfer_mode_classes[i].shift;
++		mask = ata_get_mode_mask(ap, shift);
++
++		x = fgb(mask);
++		if (x >= 0) {
++			*xfer_mode_out = xfer_mode_classes[i].base + x;
++			*xfer_shift_out = shift;
++			return 0;
+ 		}
+-
+-		i--;
+-	}
+-
+-	/* require udma for host and all attached devices */
+-	if (udma_mode < 0) {
+-		printk(KERN_WARNING "ata%u: no UltraDMA support, ignoring\n",
+-		       ap->id);
+-		goto err_out;
+ 	}
+ 
+-	for (i = 0; i < ATA_MAX_DEVICES; i++)
+-		if (ata_dev_present(&ap->device[i])) {
+-			ap->device[i].udma_mode = udma_mode;
+-			if (ap->ops->set_udmamode)
+-				ap->ops->set_udmamode(ap, &ap->device[i],
+-						      udma_mode);
+-		}
+-
+-	return;
+-
+-err_out:
+-	ap->ops->port_disable(ap);
++	return -1;
+ }
+ 
+ /**
+@@ -1658,89 +1809,39 @@
+ 
+ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
+ {
+-	struct ata_taskfile tf;
++	DECLARE_COMPLETION(wait);
++	struct ata_queued_cmd *qc;
++	int rc;
++	unsigned long flags;
+ 
+ 	/* set up set-features taskfile */
+ 	DPRINTK("set features - xfer mode\n");
+-	ata_tf_init(ap, &tf, dev->devno);
+-	tf.ctl |= ATA_NIEN;
+-	tf.command = ATA_CMD_SET_FEATURES;
+-	tf.feature = SETFEATURES_XFER;
+-	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+-	tf.protocol = ATA_PROT_NODATA;
+-	if (dev->flags & ATA_DFLAG_PIO)
+-		tf.nsect = dev->pio_mode;
+-	else
+-		tf.nsect = dev->udma_mode;
+ 
+-	/* do bus reset */
+-	ata_tf_to_host(ap, &tf);
++	qc = ata_qc_new_init(ap, dev);
++	BUG_ON(qc == NULL);
+ 
+-	/* crazy ATAPI devices... */
+-	if (dev->class == ATA_DEV_ATAPI)
+-		msleep(150);
++	qc->tf.command = ATA_CMD_SET_FEATURES;
++	qc->tf.feature = SETFEATURES_XFER;
++	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
++	qc->tf.protocol = ATA_PROT_NODATA;
++	qc->tf.nsect = dev->xfer_mode;
+ 
+-	ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
++	qc->waiting = &wait;
++	qc->complete_fn = ata_qc_complete_noop;
+ 
+-	ata_irq_on(ap);	/* re-enable interrupts */
++	spin_lock_irqsave(&ap->host_set->lock, flags);
++	rc = ata_qc_issue(qc);
++	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+ 
+-	ata_wait_idle(ap);
++	if (rc)
++		ata_port_disable(ap);
++	else
++		wait_for_completion(&wait);
+ 
+ 	DPRINTK("EXIT\n");
+ }
+ 
+ /**
+- *	ata_dev_set_udma - Set ATA device's transfer mode to Ultra DMA
+- *	@ap: Port associated with device @dev
+- *	@device: Device whose mode will be set
+- *
+- *	LOCKING:
+- */
+-
+-static void ata_dev_set_udma(struct ata_port *ap, unsigned int device)
+-{
+-	struct ata_device *dev = &ap->device[device];
+-
+-	if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
+-		return;
+-
+-	ata_dev_set_xfermode(ap, dev);
+-
+-	assert((dev->udma_mode >= XFER_UDMA_0) &&
+-	       (dev->udma_mode <= XFER_UDMA_7));
+-	printk(KERN_INFO "ata%u: dev %u configured for %s\n",
+-	       ap->id, device,
+-	       udma_str[dev->udma_mode - XFER_UDMA_0]);
+-}
+-
+-/**
+- *	ata_dev_set_pio - Set ATA device's transfer mode to PIO
+- *	@ap: Port associated with device @dev
+- *	@device: Device whose mode will be set
+- *
+- *	LOCKING:
+- */
+-
+-static void ata_dev_set_pio(struct ata_port *ap, unsigned int device)
+-{
+-	struct ata_device *dev = &ap->device[device];
+-
+-	if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
+-		return;
+-
+-	/* force PIO mode */
+-	dev->flags |= ATA_DFLAG_PIO;
+-
+-	ata_dev_set_xfermode(ap, dev);
+-
+-	assert((dev->pio_mode >= XFER_PIO_3) &&
+-	       (dev->pio_mode <= XFER_PIO_4));
+-	printk(KERN_INFO "ata%u: dev %u configured for PIO%c\n",
+-	       ap->id, device,
+-	       dev->pio_mode == 3 ? '3' : '4');
+-}
+-
+-/**
+  *	ata_sg_clean -
+  *	@qc:
+  *
+@@ -1751,7 +1852,7 @@
+ {
+ 	struct ata_port *ap = qc->ap;
+ 	struct scatterlist *sg = qc->sg;
+-	int dir = qc->pci_dma_dir;
++	int dir = qc->dma_dir;
+ 
+ 	assert(qc->flags & ATA_QCFLAG_DMAMAP);
+ 	assert(sg != NULL);
+@@ -1762,9 +1863,9 @@
+ 	DPRINTK("unmapping %u sg elements\n", qc->n_elem);
+ 
+ 	if (qc->flags & ATA_QCFLAG_SG)
+-		pci_unmap_sg(ap->host_set->pdev, sg, qc->n_elem, dir);
++		dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir);
+ 	else
+-		pci_unmap_single(ap->host_set->pdev, sg_dma_address(&sg[0]),
++		dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]),
+ 				 sg_dma_len(&sg[0]), dir);
+ 
+ 	qc->flags &= ~ATA_QCFLAG_DMAMAP;
+@@ -1789,7 +1890,7 @@
+ 
+ 	idx = 0;
+ 	for (nelem = qc->n_elem; nelem; nelem--,sg++) {
+-		u32 addr, boundary;
++		u32 addr, offset;
+ 		u32 sg_len, len;
+ 
+ 		/* determine if physical DMA addr spans 64K boundary.
+@@ -1800,10 +1901,10 @@
+ 		sg_len = sg_dma_len(sg);
+ 
+ 		while (sg_len) {
+-			boundary = (addr & ~0xffff) + (0xffff + 1);
++			offset = addr & 0xffff;
+ 			len = sg_len;
+-			if ((addr + sg_len) > boundary)
+-				len = boundary - addr;
++			if ((offset + sg_len) > 0x10000)
++				len = 0x10000 - offset;
+ 
+ 			ap->prd[idx].addr = cpu_to_le32(addr);
+ 			ap->prd[idx].flags_len = cpu_to_le32(len & 0xffff);
+@@ -1849,8 +1950,6 @@
+ 	sg->page = virt_to_page(buf);
+ 	sg->offset = (unsigned long) buf & ~PAGE_MASK;
+ 	sg_dma_len(sg) = buflen;
+-
+-	WARN_ON(buflen > PAGE_SIZE);
+ }
+ 
+ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
+@@ -1875,13 +1974,13 @@
+ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
+ {
+ 	struct ata_port *ap = qc->ap;
+-	int dir = qc->pci_dma_dir;
++	int dir = qc->dma_dir;
+ 	struct scatterlist *sg = qc->sg;
+ 	dma_addr_t dma_address;
+ 
+-	dma_address = pci_map_single(ap->host_set->pdev, qc->buf_virt,
++	dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
+ 				     sg_dma_len(sg), dir);
+-	if (pci_dma_mapping_error(dma_address))
++	if (dma_mapping_error(dma_address))
+ 		return -1;
+ 
+ 	sg_dma_address(sg) = dma_address;
+@@ -1912,8 +2011,8 @@
+ 	VPRINTK("ENTER, ata%u\n", ap->id);
+ 	assert(qc->flags & ATA_QCFLAG_SG);
+ 
+-	dir = qc->pci_dma_dir;
+-	n_elem = pci_map_sg(ap->host_set->pdev, sg, qc->n_elem, dir);
++	dir = qc->dma_dir;
++	n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir);
+ 	if (n_elem < 1)
+ 		return -1;
+ 
+@@ -2003,7 +2102,7 @@
+ 	}
+ 
+ 	drv_stat = ata_wait_idle(ap);
+-	if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
++	if (!ata_ok(drv_stat)) {
+ 		ap->pio_task_state = PIO_ST_ERR;
+ 		return;
+ 	}
+@@ -2018,24 +2117,191 @@
+ 	ata_qc_complete(qc, drv_stat);
+ }
+ 
+-/**
+- *	ata_pio_sector -
+- *	@ap:
+- *
+- *	LOCKING:
+- */
++void swap_buf_le16(u16 *buf, unsigned int buf_words)
++{
++#ifdef __BIG_ENDIAN
++	unsigned int i;
++
++	for (i = 0; i < buf_words; i++)
++		buf[i] = le16_to_cpu(buf[i]);
++#endif /* __BIG_ENDIAN */
++}
+ 
+-static void ata_pio_sector(struct ata_port *ap)
++static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf,
++			       unsigned int buflen, int write_data)
+ {
+-	struct ata_queued_cmd *qc;
+-	struct scatterlist *sg;
+-	struct page *page;
+-	unsigned char *buf;
+-	u8 status;
++	unsigned int i;
++	unsigned int words = buflen >> 1;
++	u16 *buf16 = (u16 *) buf;
++	void *mmio = (void *)ap->ioaddr.data_addr;
++
++	if (write_data) {
++		for (i = 0; i < words; i++)
++			writew(le16_to_cpu(buf16[i]), mmio);
++	} else {
++		for (i = 0; i < words; i++)
++			buf16[i] = cpu_to_le16(readw(mmio));
++	}
++}
+ 
+-	/*
+-	 * This is purely hueristic.  This is a fast path.
+-	 * Sometimes when we enter, BSY will be cleared in
++static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf,
++			      unsigned int buflen, int write_data)
++{
++	unsigned int dwords = buflen >> 1;
++
++	if (write_data)
++		outsw(ap->ioaddr.data_addr, buf, dwords);
++	else
++		insw(ap->ioaddr.data_addr, buf, dwords);
++}
++
++static void ata_data_xfer(struct ata_port *ap, unsigned char *buf,
++			  unsigned int buflen, int do_write)
++{
++	if (ap->flags & ATA_FLAG_MMIO)
++		ata_mmio_data_xfer(ap, buf, buflen, do_write);
++	else
++		ata_pio_data_xfer(ap, buf, buflen, do_write);
++}
++
++static void ata_pio_sector(struct ata_queued_cmd *qc)
++{
++	int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
++	struct scatterlist *sg = qc->sg;
++	struct ata_port *ap = qc->ap;
++	struct page *page;
++	unsigned int offset;
++	unsigned char *buf;
++
++	if (qc->cursect == (qc->nsect - 1))
++		ap->pio_task_state = PIO_ST_LAST;
++
++	page = sg[qc->cursg].page;
++	offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
++
++	/* get the current page and offset */
++	page = nth_page(page, (offset >> PAGE_SHIFT));
++	offset %= PAGE_SIZE;
++
++	buf = kmap(page) + offset;
++
++	qc->cursect++;
++	qc->cursg_ofs++;
++
++	if ((qc->cursg_ofs * ATA_SECT_SIZE) == sg_dma_len(&sg[qc->cursg])) {
++		qc->cursg++;
++		qc->cursg_ofs = 0;
++	}
++
++	DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
++
++	/* do the actual data transfer */
++	do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
++	ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write);
++
++	kunmap(page);
++}
++
++static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
++{
++	int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
++	struct scatterlist *sg = qc->sg;
++	struct ata_port *ap = qc->ap;
++	struct page *page;
++	unsigned char *buf;
++	unsigned int offset, count;
++
++	if (qc->curbytes == qc->nbytes - bytes)
++		ap->pio_task_state = PIO_ST_LAST;
++
++next_sg:
++	sg = &qc->sg[qc->cursg];
++
++next_page:
++	page = sg->page;
++	offset = sg->offset + qc->cursg_ofs;
++
++	/* get the current page and offset */
++	page = nth_page(page, (offset >> PAGE_SHIFT));
++	offset %= PAGE_SIZE;
++
++	count = min(sg_dma_len(sg) - qc->cursg_ofs, bytes);
++
++	/* don't cross page boundaries */
++	count = min(count, (unsigned int)PAGE_SIZE - offset);
++
++	buf = kmap(page) + offset;
++
++	bytes -= count;
++	qc->curbytes += count;
++	qc->cursg_ofs += count;
++
++	if (qc->cursg_ofs == sg_dma_len(sg)) {
++		qc->cursg++;
++		qc->cursg_ofs = 0;
++	}
++
++	DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
++
++	/* do the actual data transfer */
++	ata_data_xfer(ap, buf, count, do_write);
++
++	kunmap(page);
++
++	if (bytes) {
++		if (qc->cursg_ofs < sg_dma_len(sg))
++			goto next_page;
++		goto next_sg;
++	}
++}
++
++static void atapi_pio_bytes(struct ata_queued_cmd *qc)
++{
++	struct ata_port *ap = qc->ap;
++	struct ata_device *dev = qc->dev;
++	unsigned int ireason, bc_lo, bc_hi, bytes;
++	int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
++
++	ap->ops->tf_read(ap, &qc->tf);
++	ireason = qc->tf.nsect;
++	bc_lo = qc->tf.lbam;
++	bc_hi = qc->tf.lbah;
++	bytes = (bc_hi << 8) | bc_lo;
++
++	/* shall be cleared to zero, indicating xfer of data */
++	if (ireason & (1 << 0))
++		goto err_out;
++
++	/* make sure transfer direction matches expected */
++	i_write = ((ireason & (1 << 1)) == 0) ? 1 : 0;
++	if (do_write != i_write)
++		goto err_out;
++
++	__atapi_pio_bytes(qc, bytes);
++
++	return;
++
++err_out:
++	printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
++	      ap->id, dev->devno);
++	ap->pio_task_state = PIO_ST_ERR;
++}
++
++/**
++ *	ata_pio_sector -
++ *	@ap:
++ *
++ *	LOCKING:
++ */
++
++static void ata_pio_block(struct ata_port *ap)
++{
++	struct ata_queued_cmd *qc;
++	u8 status;
++
++	/*
++	 * This is purely hueristic.  This is a fast path.
++	 * Sometimes when we enter, BSY will be cleared in
+ 	 * a chk-status or two.  If not, the drive is probably seeking
+ 	 * or something.  Snooze for a couple msecs, then
+ 	 * chk-status again.  If still busy, fall back to
+@@ -2052,45 +2318,49 @@
+ 		}
+ 	}
+ 
+-	/* handle BSY=0, DRQ=0 as error */
+-	if ((status & ATA_DRQ) == 0) {
+-		ap->pio_task_state = PIO_ST_ERR;
+-		return;
+-	}
+-
+ 	qc = ata_qc_from_tag(ap, ap->active_tag);
+ 	assert(qc != NULL);
+ 
+-	sg = qc->sg;
++	if (is_atapi_taskfile(&qc->tf)) {
++		/* no more data to transfer or unsupported ATAPI command */
++		if ((status & ATA_DRQ) == 0) {
++			ap->pio_task_state = PIO_ST_IDLE;
+ 
+-	if (qc->cursect == (qc->nsect - 1))
+-		ap->pio_task_state = PIO_ST_LAST;
+-
+-	page = sg[qc->cursg].page;
+-	buf = kmap(page) +
+-	      sg[qc->cursg].offset + (qc->cursg_ofs * ATA_SECT_SIZE);
++			ata_irq_on(ap);
+ 
+-	qc->cursect++;
+-	qc->cursg_ofs++;
++			ata_qc_complete(qc, status);
++			return;
++		}
+ 
+-	if (qc->flags & ATA_QCFLAG_SG)
+-		if ((qc->cursg_ofs * ATA_SECT_SIZE) == sg_dma_len(&sg[qc->cursg])) {
+-			qc->cursg++;
+-			qc->cursg_ofs = 0;
++		atapi_pio_bytes(qc);
++	} else {
++		/* handle BSY=0, DRQ=0 as error */
++		if ((status & ATA_DRQ) == 0) {
++			ap->pio_task_state = PIO_ST_ERR;
++			return;
+ 		}
+ 
+-	DPRINTK("data %s, drv_stat 0x%X\n",
+-		qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read",
+-		status);
++		ata_pio_sector(qc);
++	}
++}
+ 
+-	/* do the actual data transfer */
+-	/* FIXME: mmio-ize */
+-	if (qc->tf.flags & ATA_TFLAG_WRITE)
+-		outsl(ap->ioaddr.data_addr, buf, ATA_SECT_DWORDS);
+-	else
+-		insl(ap->ioaddr.data_addr, buf, ATA_SECT_DWORDS);
++static void ata_pio_error(struct ata_port *ap)
++{
++	struct ata_queued_cmd *qc;
++	u8 drv_stat;
+ 
+-	kunmap(page);
++	qc = ata_qc_from_tag(ap, ap->active_tag);
++	assert(qc != NULL);
++
++	drv_stat = ata_chk_status(ap);
++	printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n",
++	       ap->id, drv_stat);
++
++	ap->pio_task_state = PIO_ST_IDLE;
++
++	ata_irq_on(ap);
++
++	ata_qc_complete(qc, drv_stat | ATA_ERR);
+ }
+ 
+ static void ata_pio_task(void *_data)
+@@ -2100,7 +2370,7 @@
+ 
+ 	switch (ap->pio_task_state) {
+ 	case PIO_ST:
+-		ata_pio_sector(ap);
++		ata_pio_block(ap);
+ 		break;
+ 
+ 	case PIO_ST_LAST:
+@@ -2113,15 +2383,8 @@
+ 		break;
+ 
+ 	case PIO_ST_TMOUT:
+-		printk(KERN_ERR "ata%d: FIXME: PIO_ST_TMOUT\n", /* FIXME */
+-		       ap->id);
+-		timeout = 11 * HZ;
+-		break;
+-
+ 	case PIO_ST_ERR:
+-		printk(KERN_ERR "ata%d: FIXME: PIO_ST_ERR\n", /* FIXME */
+-		       ap->id);
+-		timeout = 11 * HZ;
++		ata_pio_error(ap);
+ 		break;
+ 	}
+ 
+@@ -2136,6 +2399,59 @@
+ 	}
+ }
+ 
++static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
++				struct scsi_cmnd *cmd)
++{
++	DECLARE_COMPLETION(wait);
++	struct ata_queued_cmd *qc;
++	unsigned long flags;
++	int using_pio = dev->flags & ATA_DFLAG_PIO;
++	int rc;
++
++	DPRINTK("ATAPI request sense\n");
++
++	qc = ata_qc_new_init(ap, dev);
++	BUG_ON(qc == NULL);
++
++	/* FIXME: is this needed? */
++	memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
++
++	ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
++	qc->dma_dir = DMA_FROM_DEVICE;
++
++	memset(&qc->cdb, 0, sizeof(ap->cdb_len));
++	qc->cdb[0] = REQUEST_SENSE;
++	qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
++
++	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
++	qc->tf.command = ATA_CMD_PACKET;
++
++	if (using_pio) {
++		qc->tf.protocol = ATA_PROT_ATAPI;
++		qc->tf.lbam = (8 * 1024) & 0xff;
++		qc->tf.lbah = (8 * 1024) >> 8;
++
++		qc->nbytes = SCSI_SENSE_BUFFERSIZE;
++	} else {
++		qc->tf.protocol = ATA_PROT_ATAPI_DMA;
++		qc->tf.feature |= ATAPI_PKT_DMA;
++	}
++
++	qc->waiting = &wait;
++	qc->complete_fn = ata_qc_complete_noop;
++
++	spin_lock_irqsave(&ap->host_set->lock, flags);
++	rc = ata_qc_issue(qc);
++	spin_unlock_irqrestore(&ap->host_set->lock, flags);
++
++	if (rc)
++		ata_port_disable(ap);
++	else
++		wait_for_completion(&wait);
++
++	DPRINTK("EXIT\n");
++}
++
+ /**
+  *	ata_qc_timeout - Handle timeout of queued command
+  *	@qc: Command that timed out
+@@ -2157,10 +2473,29 @@
+ static void ata_qc_timeout(struct ata_queued_cmd *qc)
+ {
+ 	struct ata_port *ap = qc->ap;
++	struct ata_device *dev = qc->dev;
+ 	u8 host_stat = 0, drv_stat;
+ 
+ 	DPRINTK("ENTER\n");
+ 
++	/* FIXME: doesn't this conflict with timeout handling? */
++	if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) {
++		struct scsi_cmnd *cmd = qc->scsicmd;
++
++		if (!scsi_eh_eflags_chk(cmd, SCSI_EH_CANCEL_CMD)) {
++
++			/* finish completing original command */
++			__ata_qc_complete(qc);
++
++			atapi_request_sense(ap, dev, cmd);
++
++			cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
++			scsi_finish_command(cmd);
++
++			goto out;
++		}
++	}
++
+ 	/* hack alert!  We cannot use the supplied completion
+ 	 * function from inside the ->eh_strategy_handler() thread.
+ 	 * libata is the only user of ->eh_strategy_handler() in
+@@ -2180,7 +2515,6 @@
+ 
+ 		/* fall through */
+ 
+-	case ATA_PROT_NODATA:
+ 	default:
+ 		ata_altstatus(ap);
+ 		drv_stat = ata_chk_status(ap);
+@@ -2195,7 +2529,7 @@
+ 		ata_qc_complete(qc, drv_stat);
+ 		break;
+ 	}
+-
++out:
+ 	DPRINTK("EXIT\n");
+ }
+ 
+@@ -2284,11 +2618,10 @@
+ 		qc->dev = dev;
+ 		qc->cursect = qc->cursg = qc->cursg_ofs = 0;
+ 		qc->nsect = 0;
++		qc->nbytes = qc->curbytes = 0;
+ 
+ 		ata_tf_init(ap, &qc->tf, dev->devno);
+ 
+-		if (likely((dev->flags & ATA_DFLAG_PIO) == 0))
+-			qc->flags |= ATA_QCFLAG_DMA;
+ 		if (dev->flags & ATA_DFLAG_LBA48)
+ 			qc->tf.flags |= ATA_TFLAG_LBA48;
+ 	}
+@@ -2296,6 +2629,35 @@
+ 	return qc;
+ }
+ 
++static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
++{
++	return 0;
++}
++
++static void __ata_qc_complete(struct ata_queued_cmd *qc)
++{
++	struct ata_port *ap = qc->ap;
++	unsigned int tag, do_clear = 0;
++
++	qc->flags = 0;
++	tag = qc->tag;
++	if (likely(ata_tag_valid(tag))) {
++		if (tag == ap->active_tag)
++			ap->active_tag = ATA_TAG_POISON;
++		qc->tag = ATA_TAG_POISON;
++		do_clear = 1;
++	}
++
++	if (qc->waiting) {
++		struct completion *waiting = qc->waiting;
++		qc->waiting = NULL;
++		complete(waiting);
++	}
++
++	if (likely(do_clear))
++		clear_bit(tag, &ap->qactive);
++}
++
+ /**
+  *	ata_qc_complete - Complete an active ATA command
+  *	@qc: Command to complete
+@@ -2307,8 +2669,6 @@
+ 
+ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+ {
+-	struct ata_port *ap = qc->ap;
+-	unsigned int tag, do_clear = 0;
+ 	int rc;
+ 
+ 	assert(qc != NULL);	/* ata_qc_from_tag _might_ return NULL */
+@@ -2326,20 +2686,33 @@
+ 	if (rc != 0)
+ 		return;
+ 
+-	qc->flags = 0;
+-	tag = qc->tag;
+-	if (likely(ata_tag_valid(tag))) {
+-		if (tag == ap->active_tag)
+-			ap->active_tag = ATA_TAG_POISON;
+-		qc->tag = ATA_TAG_POISON;
+-		do_clear = 1;
+-	}
++	__ata_qc_complete(qc);
+ 
+-	if (qc->waiting)
+-		complete(qc->waiting);
++	VPRINTK("EXIT\n");
++}
+ 
+-	if (likely(do_clear))
+-		clear_bit(tag, &ap->qactive);
++static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
++{
++	struct ata_port *ap = qc->ap;
++
++	switch (qc->tf.protocol) {
++	case ATA_PROT_DMA:
++	case ATA_PROT_ATAPI_DMA:
++		return 1;
++
++	case ATA_PROT_ATAPI:
++	case ATA_PROT_PIO:
++	case ATA_PROT_PIO_MULT:
++		if (ap->flags & ATA_FLAG_PIO_DMA)
++			return 1;
++
++		/* fall through */
++	
++	default:
++		return 0;
++	}
++
++	/* never reached */
+ }
+ 
+ /**
+@@ -2362,12 +2735,16 @@
+ {
+ 	struct ata_port *ap = qc->ap;
+ 
+-	if (qc->flags & ATA_QCFLAG_SG) {
+-		if (ata_sg_setup(qc))
+-			goto err_out;
+-	} else if (qc->flags & ATA_QCFLAG_SINGLE) {
+-		if (ata_sg_setup_one(qc))
+-			goto err_out;
++	if (ata_should_dma_map(qc)) {
++		if (qc->flags & ATA_QCFLAG_SG) {
++			if (ata_sg_setup(qc))
++				goto err_out;
++		} else if (qc->flags & ATA_QCFLAG_SINGLE) {
++			if (ata_sg_setup_one(qc))
++				goto err_out;
++		}
++	} else {
++		qc->flags &= ~ATA_QCFLAG_DMAMAP;
+ 	}
+ 
+ 	ap->ops->qc_prep(qc);
+@@ -2422,6 +2799,12 @@
+ 		break;
+ 
+ 	case ATA_PROT_ATAPI:
++		ata_qc_set_polling(qc);
++		ata_tf_to_host_nolock(ap, &qc->tf);
++		queue_work(ata_wq, &ap->packet_task);
++		break;
++
++	case ATA_PROT_ATAPI_NODATA:
+ 		ata_tf_to_host_nolock(ap, &qc->tf);
+ 		queue_work(ata_wq, &ap->packet_task);
+ 		break;
+@@ -2441,14 +2824,14 @@
+ }
+ 
+ /**
+- *	ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction (MMIO)
++ *	ata_bmdma_setup - Set up PCI IDE BMDMA transaction
+  *	@qc: Info associated with this ATA transaction.
+  *
+  *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc)
++static void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc)
+ {
+ 	struct ata_port *ap = qc->ap;
+ 	unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
+@@ -2471,14 +2854,14 @@
+ }
+ 
+ /**
+- *	ata_bmdma_start_mmio - Start a PCI IDE BMDMA transaction (MMIO)
++ *	ata_bmdma_start - Start a PCI IDE BMDMA transaction
+  *	@qc: Info associated with this ATA transaction.
+  *
+  *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
++static void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
+ {
+ 	struct ata_port *ap = qc->ap;
+ 	void *mmio = (void *) ap->ioaddr.bmdma_addr;
+@@ -2509,7 +2892,7 @@
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-void ata_bmdma_setup_pio (struct ata_queued_cmd *qc)
++static void ata_bmdma_setup_pio (struct ata_queued_cmd *qc)
+ {
+ 	struct ata_port *ap = qc->ap;
+ 	unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
+@@ -2537,7 +2920,7 @@
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
++static void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
+ {
+ 	struct ata_port *ap = qc->ap;
+ 	u8 dmactl;
+@@ -2548,6 +2931,22 @@
+ 	     ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ }
+ 
++void ata_bmdma_start(struct ata_queued_cmd *qc)
++{
++	if (qc->ap->flags & ATA_FLAG_MMIO)
++		ata_bmdma_start_mmio(qc);
++	else
++		ata_bmdma_start_pio(qc);
++}
++
++void ata_bmdma_setup(struct ata_queued_cmd *qc)
++{
++	if (qc->ap->flags & ATA_FLAG_MMIO)
++		ata_bmdma_setup_mmio(qc);
++	else
++		ata_bmdma_setup_pio(qc);
++}
++
+ void ata_bmdma_irq_clear(struct ata_port *ap)
+ {
+ 	ata_bmdma_ack_irq(ap);
+@@ -2581,7 +2980,7 @@
+ 	case ATA_PROT_ATAPI:
+ 		/* check status of DMA engine */
+ 		host_stat = ata_bmdma_status(ap);
+-		VPRINTK("BUS_DMA (host_stat 0x%X)\n", host_stat);
++		VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat);
+ 
+ 		/* if it's not our irq... */
+ 		if (!(host_stat & ATA_DMA_INTR))
+@@ -2592,6 +2991,7 @@
+ 
+ 		/* fall through */
+ 
++	case ATA_PROT_ATAPI_NODATA:
+ 	case ATA_PROT_NODATA:
+ 		/* check altstatus */
+ 		status = ata_altstatus(ap);
+@@ -2602,7 +3002,8 @@
+ 		status = ata_chk_status(ap);
+ 		if (unlikely(status & ATA_BUSY))
+ 			goto idle_irq;
+-		DPRINTK("BUS_NODATA (dev_stat 0x%X)\n", status);
++		DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
++			ap->id, qc->tf.protocol, status);
+ 
+ 		/* ack bmdma irq events */
+ 		ata_bmdma_ack_irq(ap);
+@@ -2701,21 +3102,20 @@
+ 
+ 	/* make sure DRQ is set */
+ 	status = ata_chk_status(ap);
+-	if ((status & ATA_DRQ) == 0)
++	if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)
+ 		goto err_out;
+ 
+ 	/* send SCSI cdb */
+-	/* FIXME: mmio-ize */
+ 	DPRINTK("send cdb\n");
+-	outsl(ap->ioaddr.data_addr,
+-	      qc->scsicmd->cmnd, ap->host->max_cmd_len / 4);
++	assert(ap->cdb_len >= 12);
++	ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
+ 
+ 	/* if we are DMA'ing, irq handler takes over from here */
+ 	if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
+ 		ap->ops->bmdma_start(qc);	    /* initiate bmdma */
+ 
+ 	/* non-data commands are also handled via irq */
+-	else if (qc->scsicmd->sc_data_direction == SCSI_DATA_NONE) {
++	else if (qc->tf.protocol == ATA_PROT_ATAPI_NODATA) {
+ 		/* do nothing */
+ 	}
+ 
+@@ -2733,9 +3133,9 @@
+ 
+ int ata_port_start (struct ata_port *ap)
+ {
+-	struct pci_dev *pdev = ap->host_set->pdev;
++	struct device *dev = ap->host_set->dev;
+ 
+-	ap->prd = pci_alloc_consistent(pdev, ATA_PRD_TBL_SZ, &ap->prd_dma);
++	ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL);
+ 	if (!ap->prd)
+ 		return -ENOMEM;
+ 
+@@ -2746,9 +3146,9 @@
+ 
+ void ata_port_stop (struct ata_port *ap)
+ {
+-	struct pci_dev *pdev = ap->host_set->pdev;
++	struct device *dev = ap->host_set->dev;
+ 
+-	pci_free_consistent(pdev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
++	dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+ }
+ 
+ /**
+@@ -2794,7 +3194,7 @@
+ 	host->max_channel = 1;
+ 	host->unique_id = ata_unique_id++;
+ 	host->max_cmd_len = 12;
+-	scsi_set_device(host, &ent->pdev->dev);
++	scsi_set_device(host, ent->dev);
+ 	scsi_assign_lock(host, &host_set->lock);
+ 
+ 	ap->flags = ATA_FLAG_PORT_DISABLED;
+@@ -2806,11 +3206,11 @@
+ 	ap->hard_port_no =
+ 		ent->legacy_mode ? ent->hard_port_no : port_no;
+ 	ap->pio_mask = ent->pio_mask;
++	ap->mwdma_mask = ent->mwdma_mask;
+ 	ap->udma_mask = ent->udma_mask;
+ 	ap->flags |= ent->host_flags;
+ 	ap->ops = ent->port_ops;
+ 	ap->cbl = ATA_CBL_NONE;
+-	ap->device[0].flags = ATA_DFLAG_MASTER;
+ 	ap->active_tag = ATA_TAG_POISON;
+ 	ap->last_ctl = 0xFF;
+ 
+@@ -2881,7 +3281,7 @@
+ int ata_device_add(struct ata_probe_ent *ent)
+ {
+ 	unsigned int count = 0, i;
+-	struct pci_dev *pdev = ent->pdev;
++	struct device *dev = ent->dev;
+ 	struct ata_host_set *host_set;
+ 
+ 	DPRINTK("ENTER\n");
+@@ -2893,7 +3293,7 @@
+ 	memset(host_set, 0, sizeof(struct ata_host_set) + (ent->n_ports * sizeof(void *)));
+ 	spin_lock_init(&host_set->lock);
+ 
+-	host_set->pdev = pdev;
++	host_set->dev = dev;
+ 	host_set->n_ports = ent->n_ports;
+ 	host_set->irq = ent->irq;
+ 	host_set->mmio_base = ent->mmio_base;
+@@ -2903,19 +3303,23 @@
+ 	/* register each port bound to this device */
+ 	for (i = 0; i < ent->n_ports; i++) {
+ 		struct ata_port *ap;
++		unsigned long xfer_mode_mask;
+ 
+ 		ap = ata_host_add(ent, host_set, i);
+ 		if (!ap)
+ 			goto err_out;
+ 
+ 		host_set->ports[i] = ap;
++		xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) |
++				(ap->mwdma_mask << ATA_SHIFT_MWDMA) |
++				(ap->pio_mask << ATA_SHIFT_PIO);
+ 
+ 		/* print per-port info to dmesg */
+ 		printk(KERN_INFO "ata%u: %cATA max %s cmd 0x%lX ctl 0x%lX "
+ 				 "bmdma 0x%lX irq %lu\n",
+ 			ap->id,
+ 			ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
+-			ata_udma_string(ent->udma_mask),
++			ata_mode_string(xfer_mode_mask),
+ 	       		ap->ioaddr.cmd_addr,
+ 	       		ap->ioaddr.ctl_addr,
+ 	       		ap->ioaddr.bmdma_addr,
+@@ -2957,7 +3361,7 @@
+ 			 */
+ 		}
+ 
+-		rc = scsi_add_host(ap->host, &pdev->dev);
++		rc = scsi_add_host(ap->host, dev);
+ 		if (rc) {
+ 			printk(KERN_ERR "ata%u: scsi_add_host failed\n",
+ 			       ap->id);
+@@ -2977,7 +3381,7 @@
+ 		scsi_scan_host(ap->host);
+ 	}
+ 
+-	pci_set_drvdata(pdev, host_set);
++	dev_set_drvdata(dev, host_set);
+ 
+ 	VPRINTK("EXIT, returning %u\n", ent->n_ports);
+ 	return ent->n_ports; /* success */
+@@ -3037,6 +3441,104 @@
+ 	ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD;
+ }
+ 
++static struct ata_probe_ent *
++ata_probe_ent_alloc(int n, struct device *dev, struct ata_port_info **port)
++{
++	struct ata_probe_ent *probe_ent;
++	int i;
++
++	probe_ent = kmalloc(sizeof(*probe_ent) * n, GFP_KERNEL);
++	if (!probe_ent) {
++		printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
++		       kobject_name(&(dev->kobj)));
++		return NULL;
++	}
++
++	memset(probe_ent, 0, sizeof(*probe_ent) * n);
++
++	for (i = 0; i < n; i++) {
++		INIT_LIST_HEAD(&probe_ent[i].node);
++		probe_ent[i].dev = dev;
++
++		probe_ent[i].sht = port[i]->sht;
++		probe_ent[i].host_flags = port[i]->host_flags;
++		probe_ent[i].pio_mask = port[i]->pio_mask;
++		probe_ent[i].mwdma_mask = port[i]->mwdma_mask;
++		probe_ent[i].udma_mask = port[i]->udma_mask;
++		probe_ent[i].port_ops = port[i]->port_ops;
++
++	}
++
++	return probe_ent;
++}
++
++#ifdef CONFIG_PCI
++struct ata_probe_ent *
++ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
++{
++	struct ata_probe_ent *probe_ent =
++		ata_probe_ent_alloc(1, pci_dev_to_dev(pdev), port);
++	if (!probe_ent)
++		return NULL;
++
++	probe_ent->n_ports = 2;
++	probe_ent->irq = pdev->irq;
++	probe_ent->irq_flags = SA_SHIRQ;
++
++	probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
++	probe_ent->port[0].altstatus_addr =
++	probe_ent->port[0].ctl_addr =
++		pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
++	probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
++
++	probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
++	probe_ent->port[1].altstatus_addr =
++	probe_ent->port[1].ctl_addr =
++		pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
++	probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
++
++	ata_std_ports(&probe_ent->port[0]);
++	ata_std_ports(&probe_ent->port[1]);
++
++	return probe_ent;
++}
++
++struct ata_probe_ent *
++ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port)
++{
++	struct ata_probe_ent *probe_ent =
++		ata_probe_ent_alloc(2, pci_dev_to_dev(pdev), port);
++	if (!probe_ent)
++		return NULL;
++
++	probe_ent[0].n_ports = 1;
++	probe_ent[0].irq = 14;
++
++	probe_ent[0].hard_port_no = 0;
++	probe_ent[0].legacy_mode = 1;
++
++	probe_ent[1].n_ports = 1;
++	probe_ent[1].irq = 15;
++
++	probe_ent[1].hard_port_no = 1;
++	probe_ent[1].legacy_mode = 1;
++
++	probe_ent[0].port[0].cmd_addr = 0x1f0;
++	probe_ent[0].port[0].altstatus_addr =
++	probe_ent[0].port[0].ctl_addr = 0x3f6;
++	probe_ent[0].port[0].bmdma_addr = pci_resource_start(pdev, 4);
++
++	probe_ent[1].port[0].cmd_addr = 0x170;
++	probe_ent[1].port[0].altstatus_addr =
++	probe_ent[1].port[0].ctl_addr = 0x376;
++	probe_ent[1].port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
++
++	ata_std_ports(&probe_ent[0].port[0]);
++	ata_std_ports(&probe_ent[1].port[0]);
++
++	return probe_ent;
++}
++
+ /**
+  *	ata_pci_init_one - Initialize/register PCI IDE host controller
+  *	@pdev: Controller to be initialized
+@@ -3054,20 +3556,20 @@
+ 		      unsigned int n_ports)
+ {
+ 	struct ata_probe_ent *probe_ent, *probe_ent2 = NULL;
+-	struct ata_port_info *port0, *port1;
++	struct ata_port_info *port[2];
+ 	u8 tmp8, mask;
+ 	unsigned int legacy_mode = 0;
+ 	int rc;
+ 
+ 	DPRINTK("ENTER\n");
+ 
+-	port0 = port_info[0];
++	port[0] = port_info[0];
+ 	if (n_ports > 1)
+-		port1 = port_info[1];
++		port[1] = port_info[1];
+ 	else
+-		port1 = port0;
++		port[1] = port[0];
+ 
+-	if ((port0->host_flags & ATA_FLAG_NO_LEGACY) == 0) {
++	if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0) {
+ 		/* TODO: support transitioning to native mode? */
+ 		pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
+ 		mask = (1 << 2) | (1 << 0);
+@@ -3128,79 +3630,17 @@
+ 	if (rc)
+ 		goto err_out_regions;
+ 
+-	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
++	if (legacy_mode) {
++		probe_ent = ata_pci_init_legacy_mode(pdev, port);
++		if (probe_ent)
++			probe_ent2 = &probe_ent[1];
++	} else
++		probe_ent = ata_pci_init_native_mode(pdev, port);
+ 	if (!probe_ent) {
+ 		rc = -ENOMEM;
+ 		goto err_out_regions;
+ 	}
+ 
+-	memset(probe_ent, 0, sizeof(*probe_ent));
+-	probe_ent->pdev = pdev;
+-	INIT_LIST_HEAD(&probe_ent->node);
+-
+-	if (legacy_mode) {
+-		probe_ent2 = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+-		if (!probe_ent2) {
+-			rc = -ENOMEM;
+-			goto err_out_free_ent;
+-		}
+-
+-		memset(probe_ent2, 0, sizeof(*probe_ent));
+-		probe_ent2->pdev = pdev;
+-		INIT_LIST_HEAD(&probe_ent2->node);
+-	}
+-
+-	probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
+-	probe_ent->sht = port0->sht;
+-	probe_ent->host_flags = port0->host_flags;
+-	probe_ent->pio_mask = port0->pio_mask;
+-	probe_ent->udma_mask = port0->udma_mask;
+-	probe_ent->port_ops = port0->port_ops;
+-
+-	if (legacy_mode) {
+-		probe_ent->port[0].cmd_addr = 0x1f0;
+-		probe_ent->port[0].altstatus_addr =
+-		probe_ent->port[0].ctl_addr = 0x3f6;
+-		probe_ent->n_ports = 1;
+-		probe_ent->irq = 14;
+-		probe_ent->hard_port_no = 0;
+-		probe_ent->legacy_mode = 1;
+-		ata_std_ports(&probe_ent->port[0]);
+-
+-		probe_ent2->port[0].cmd_addr = 0x170;
+-		probe_ent2->port[0].altstatus_addr =
+-		probe_ent2->port[0].ctl_addr = 0x376;
+-		probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
+-		probe_ent2->n_ports = 1;
+-		probe_ent2->irq = 15;
+-		probe_ent->hard_port_no = 1;
+-		probe_ent->legacy_mode = 1;
+-		ata_std_ports(&probe_ent2->port[0]);
+-
+-		probe_ent2->sht = port1->sht;
+-		probe_ent2->host_flags = port1->host_flags;
+-		probe_ent2->pio_mask = port1->pio_mask;
+-		probe_ent2->udma_mask = port1->udma_mask;
+-		probe_ent2->port_ops = port1->port_ops;
+-	} else {
+-		probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
+-		ata_std_ports(&probe_ent->port[0]);
+-		probe_ent->port[0].altstatus_addr =
+-		probe_ent->port[0].ctl_addr =
+-			pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
+-
+-		probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
+-		ata_std_ports(&probe_ent->port[1]);
+-		probe_ent->port[1].altstatus_addr =
+-		probe_ent->port[1].ctl_addr =
+-			pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
+-		probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
+-
+-		probe_ent->n_ports = 2;
+-		probe_ent->irq = pdev->irq;
+-		probe_ent->irq_flags = SA_SHIRQ;
+-	}
+-
+ 	pci_set_master(pdev);
+ 
+ 	/* FIXME: check ata_device_add return */
+@@ -3209,17 +3649,13 @@
+ 			ata_device_add(probe_ent);
+ 		if (legacy_mode & (1 << 1))
+ 			ata_device_add(probe_ent2);
+-		kfree(probe_ent2);
+ 	} else {
+ 		ata_device_add(probe_ent);
+-		assert(probe_ent2 == NULL);
+ 	}
+ 	kfree(probe_ent);
+ 
+ 	return 0;
+ 
+-err_out_free_ent:
+-	kfree(probe_ent);
+ err_out_regions:
+ 	if (legacy_mode & (1 << 0))
+ 		release_region(0x1f0, 8);
+@@ -3247,7 +3683,8 @@
+ 
+ void ata_pci_remove_one (struct pci_dev *pdev)
+ {
+-	struct ata_host_set *host_set = pci_get_drvdata(pdev);
++	struct device *dev = pci_dev_to_dev(pdev);
++	struct ata_host_set *host_set = dev_get_drvdata(dev);
+ 	struct ata_port *ap;
+ 	unsigned int i;
+ 
+@@ -3288,7 +3725,7 @@
+ 
+ 	kfree(host_set);
+ 	pci_disable_device(pdev);
+-	pci_set_drvdata(pdev, NULL);
++	dev_set_drvdata(dev, NULL);
+ }
+ 
+ /* move to PCI subsystem */
+@@ -3324,6 +3761,7 @@
+ 
+ 	return (tmp == bits->val) ? 1 : 0;
+ }
++#endif /* CONFIG_PCI */
+ 
+ 
+ /**
+@@ -3360,7 +3798,6 @@
+  * Do not depend on ABI/API stability.
+  */
+ 
+-EXPORT_SYMBOL_GPL(pci_test_config_bits);
+ EXPORT_SYMBOL_GPL(ata_std_bios_param);
+ EXPORT_SYMBOL_GPL(ata_std_ports);
+ EXPORT_SYMBOL_GPL(ata_device_add);
+@@ -3369,34 +3806,40 @@
+ EXPORT_SYMBOL_GPL(ata_qc_complete);
+ EXPORT_SYMBOL_GPL(ata_qc_issue_prot);
+ EXPORT_SYMBOL_GPL(ata_eng_timeout);
+-EXPORT_SYMBOL_GPL(ata_tf_load_pio);
+-EXPORT_SYMBOL_GPL(ata_tf_load_mmio);
+-EXPORT_SYMBOL_GPL(ata_tf_read_pio);
+-EXPORT_SYMBOL_GPL(ata_tf_read_mmio);
++EXPORT_SYMBOL_GPL(ata_tf_load);
++EXPORT_SYMBOL_GPL(ata_tf_read);
++EXPORT_SYMBOL_GPL(ata_noop_dev_select);
++EXPORT_SYMBOL_GPL(ata_std_dev_select);
+ EXPORT_SYMBOL_GPL(ata_tf_to_fis);
+ EXPORT_SYMBOL_GPL(ata_tf_from_fis);
+-EXPORT_SYMBOL_GPL(ata_check_status_pio);
+-EXPORT_SYMBOL_GPL(ata_check_status_mmio);
+-EXPORT_SYMBOL_GPL(ata_exec_command_pio);
+-EXPORT_SYMBOL_GPL(ata_exec_command_mmio);
++EXPORT_SYMBOL_GPL(ata_check_status);
++EXPORT_SYMBOL_GPL(ata_exec_command);
+ EXPORT_SYMBOL_GPL(ata_port_start);
+ EXPORT_SYMBOL_GPL(ata_port_stop);
+ EXPORT_SYMBOL_GPL(ata_interrupt);
+ EXPORT_SYMBOL_GPL(ata_qc_prep);
+-EXPORT_SYMBOL_GPL(ata_bmdma_setup_pio);
+-EXPORT_SYMBOL_GPL(ata_bmdma_start_pio);
+-EXPORT_SYMBOL_GPL(ata_bmdma_setup_mmio);
+-EXPORT_SYMBOL_GPL(ata_bmdma_start_mmio);
++EXPORT_SYMBOL_GPL(ata_bmdma_setup);
++EXPORT_SYMBOL_GPL(ata_bmdma_start);
+ EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
+ EXPORT_SYMBOL_GPL(ata_port_probe);
+ EXPORT_SYMBOL_GPL(sata_phy_reset);
++EXPORT_SYMBOL_GPL(__sata_phy_reset);
+ EXPORT_SYMBOL_GPL(ata_bus_reset);
+ EXPORT_SYMBOL_GPL(ata_port_disable);
+-EXPORT_SYMBOL_GPL(ata_pci_init_one);
+-EXPORT_SYMBOL_GPL(ata_pci_remove_one);
++EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
+ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
+ EXPORT_SYMBOL_GPL(ata_scsi_error);
+ EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
+ EXPORT_SYMBOL_GPL(ata_scsi_release);
+ EXPORT_SYMBOL_GPL(ata_host_intr);
++EXPORT_SYMBOL_GPL(ata_dev_classify);
+ EXPORT_SYMBOL_GPL(ata_dev_id_string);
++EXPORT_SYMBOL_GPL(ata_scsi_simulate);
++
++#ifdef CONFIG_PCI
++EXPORT_SYMBOL_GPL(pci_test_config_bits);
++EXPORT_SYMBOL_GPL(ata_pci_init_legacy_mode);
++EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
++EXPORT_SYMBOL_GPL(ata_pci_init_one);
++EXPORT_SYMBOL_GPL(ata_pci_remove_one);
++#endif /* CONFIG_PCI */
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/libata-scsi.c kernel-source-2.6.8-2.6.8/drivers/scsi/libata-scsi.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/libata-scsi.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/libata-scsi.c	2006-08-11 14:32:25.485704175 -0600
+@@ -29,13 +29,13 @@
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
++#include <asm/uaccess.h>
+ 
+ #include "libata.h"
+ 
+ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, u8 *scsicmd);
+-static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
+-			      struct scsi_cmnd *cmd,
+-			      void (*done)(struct scsi_cmnd *));
++static struct ata_device *
++ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev);
+ 
+ 
+ /**
+@@ -67,6 +67,43 @@
+ 	return 0;
+ }
+ 
++int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
++{
++	struct ata_port *ap;
++	struct ata_device *dev;
++	int val = -EINVAL, rc = -EINVAL;
++
++	ap = (struct ata_port *) &scsidev->host->hostdata[0];
++	if (!ap)
++		goto out;
++
++	dev = ata_scsi_find_dev(ap, scsidev);
++	if (!dev) {
++		rc = -ENODEV;
++		goto out;
++	}
++
++	switch (cmd) {
++	case ATA_IOC_GET_IO32:
++		val = 0;
++		if (copy_to_user(arg, &val, 1))
++			return -EFAULT;
++		return 0;
++
++	case ATA_IOC_SET_IO32:
++		val = (unsigned long) arg;
++		if (val != 0)
++			return -EINVAL;
++		return 0;
++
++	default:
++		rc = -ENOTTY;
++		break;
++	}
++
++out:
++	return rc;
++}
+ 
+ /**
+  *	ata_scsi_qc_new - acquire new ata_queued_cmd reference
+@@ -119,35 +156,160 @@
+ /**
+  *	ata_to_sense_error - convert ATA error to SCSI error
+  *	@qc: Command that we are erroring out
++ *	@drv_stat: value contained in ATA status register
+  *
+- *	Converts an ATA error into a SCSI error.
+- *
+- *	Right now, this routine is laughably primitive.  We
+- *	don't even examine what ATA told us, we just look at
+- *	the command data direction, and return a fatal SCSI
+- *	sense error based on that.
++ *	Converts an ATA error into a SCSI error. While we are at it
++ *	we decode and dump the ATA error for the user so that they
++ *	have some idea what really happened at the non make-believe
++ *	layer.
+  *
+  *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-void ata_to_sense_error(struct ata_queued_cmd *qc)
++void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
+ {
+ 	struct scsi_cmnd *cmd = qc->scsicmd;
++	u8 err = 0;
++	unsigned char *sb = cmd->sense_buffer;
++	/* Based on the 3ware driver translation table */
++	static unsigned char sense_table[][4] = {
++		/* BBD|ECC|ID|MAR */
++		{0xd1, 		ABORTED_COMMAND, 0x00, 0x00}, 	// Device busy                  Aborted command
++		/* BBD|ECC|ID */
++		{0xd0,  	ABORTED_COMMAND, 0x00, 0x00}, 	// Device busy                  Aborted command
++		/* ECC|MC|MARK */
++		{0x61, 		HARDWARE_ERROR, 0x00, 0x00}, 	// Device fault                 Hardware error
++		/* ICRC|ABRT */		/* NB: ICRC & !ABRT is BBD */
++		{0x84, 		ABORTED_COMMAND, 0x47, 0x00}, 	// Data CRC error               SCSI parity error
++		/* MC|ID|ABRT|TRK0|MARK */
++		{0x37, 		NOT_READY, 0x04, 0x00}, 	// Unit offline                 Not ready
++		/* MCR|MARK */
++		{0x09, 		NOT_READY, 0x04, 0x00}, 	// Unrecovered disk error       Not ready
++		/*  Bad address mark */
++		{0x01, 		MEDIUM_ERROR, 0x13, 0x00}, 	// Address mark not found       Address mark not found for data field
++		/* TRK0 */
++		{0x02, 		HARDWARE_ERROR, 0x00, 0x00}, 	// Track 0 not found		  Hardware error
++		/* Abort & !ICRC */
++		{0x04, 		ABORTED_COMMAND, 0x00, 0x00}, 	// Aborted command              Aborted command
++		/* Media change request */
++		{0x08, 		NOT_READY, 0x04, 0x00}, 	// Media change request	  FIXME: faking offline
++		/* SRV */
++		{0x10, 		ABORTED_COMMAND, 0x14, 0x00}, 	// ID not found                 Recorded entity not found
++		/* Media change */
++		{0x08,  	NOT_READY, 0x04, 0x00}, 	// Media change		  FIXME: faking offline
++		/* ECC */
++		{0x40, 		MEDIUM_ERROR, 0x11, 0x04}, 	// Uncorrectable ECC error      Unrecovered read error
++		/* BBD - block marked bad */
++		{0x80, 		MEDIUM_ERROR, 0x11, 0x04}, 	// Block marked bad		  Medium error, unrecovered read error
++		{0xFF, 0xFF, 0xFF, 0xFF}, // END mark 
++	};
++	static unsigned char stat_table[][4] = {
++		/* Must be first because BUSY means no other bits valid */
++		{0x80, 		ABORTED_COMMAND, 0x47, 0x00},	// Busy, fake parity for now
++		{0x20, 		HARDWARE_ERROR,  0x00, 0x00}, 	// Device fault
++		{0x08, 		ABORTED_COMMAND, 0x47, 0x00},	// Timed out in xfer, fake parity for now
++		{0x04, 		RECOVERED_ERROR, 0x11, 0x00},	// Recovered ECC error	  Medium error, recovered
++		{0xFF, 0xFF, 0xFF, 0xFF}, // END mark 
++	};
++	int i = 0;
+ 
+ 	cmd->result = SAM_STAT_CHECK_CONDITION;
+-
+-	cmd->sense_buffer[0] = 0x70;
+-	cmd->sense_buffer[2] = MEDIUM_ERROR;
+-	cmd->sense_buffer[7] = 14 - 8;	/* addnl. sense len. FIXME: correct? */
+-
++	
++	/*
++	 *	Is this an error we can process/parse
++	 */
++	 
++	if(drv_stat & ATA_ERR)
++		/* Read the err bits */
++		err = ata_chk_err(qc->ap);
++
++	/* Display the ATA level error info */
++	
++	printk(KERN_WARNING "ata%u: status=0x%02x { ", qc->ap->id, drv_stat);
++	if(drv_stat & 0x80)
++	{
++		printk("Busy ");
++		err = 0;	/* Data is not valid in this case */
++	}
++	else {
++		if(drv_stat & 0x40)	printk("DriveReady ");
++		if(drv_stat & 0x20)	printk("DeviceFault ");
++		if(drv_stat & 0x10)	printk("SeekComplete ");
++		if(drv_stat & 0x08)	printk("DataRequest ");
++		if(drv_stat & 0x04)	printk("CorrectedError ");
++		if(drv_stat & 0x02)	printk("Index ");
++		if(drv_stat & 0x01)	printk("Error ");
++	}
++	printk("}\n");
++	
++	if(err)
++	{
++		printk(KERN_WARNING "ata%u: error=0x%02x { ", qc->ap->id, err);
++		if(err & 0x04)		printk("DriveStatusError ");
++		if(err & 0x80)
++		{
++			if(err & 0x04)
++				printk("BadCRC ");
++			else
++				printk("Sector ");
++		}
++		if(err & 0x40)		printk("UncorrectableError ");
++		if(err & 0x10)		printk("SectorIdNotFound ");
++		if(err & 0x02)		printk("TrackZeroNotFound ");
++		if(err & 0x01)		printk("AddrMarkNotFound ");
++		printk("}\n");
++		
++		/* Should we dump sector info here too ?? */
++	}
++		
++	
++	/* Look for err */
++	while(sense_table[i][0] != 0xFF)
++	{
++		/* Look for best matches first */
++		if((sense_table[i][0] & err) == sense_table[i][0])
++		{
++			sb[0] = 0x70;
++			sb[2] = sense_table[i][1];
++			sb[7] = 0x0a;
++			sb[12] = sense_table[i][2];
++			sb[13] = sense_table[i][3];
++			return;
++		}
++		i++;
++	}
++	/* No immediate match */
++	if(err)
++		printk(KERN_DEBUG "ata%u: no sense translation for 0x%02x\n", qc->ap->id, err);
++	
++	/* Fall back to interpreting status bits */
++	while(stat_table[i][0] != 0xFF)
++	{
++		if(stat_table[i][0] & drv_stat)
++		{
++			sb[0] = 0x70;
++			sb[2] = stat_table[i][1];
++			sb[7] = 0x0a;
++			sb[12] = stat_table[i][2];
++			sb[13] = stat_table[i][3];
++			return;
++		}
++		i++;
++	}
++	/* No error ?? */
++	printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat);
+ 	/* additional-sense-code[-qualifier] */
++	
++	sb[0] = 0x70;
++	sb[2] = MEDIUM_ERROR;
++	sb[7] = 0x0A;
+ 	if (cmd->sc_data_direction == SCSI_DATA_READ) {
+-		cmd->sense_buffer[12] = 0x11; /* "unrecovered read error" */
+-		cmd->sense_buffer[13] = 0x04;
++		sb[12] = 0x11; /* "unrecovered read error" */
++		sb[13] = 0x04;
+ 	} else {
+-		cmd->sense_buffer[12] = 0x0C; /* "write error -             */
+-		cmd->sense_buffer[13] = 0x02; /*  auto-reallocation failed" */
++		sb[12] = 0x0C; /* "write error -             */
++		sb[13] = 0x02; /*  auto-reallocation failed" */
+ 	}
+ }
+ 
+@@ -214,11 +376,135 @@
+ 	ap = (struct ata_port *) &host->hostdata[0];
+ 	ap->ops->eng_timeout(ap);
+ 
++	/* TODO: this is per-command; when queueing is supported
++	 * this code will either change or move to a more
++	 * appropriate place
++	 */
++	host->host_failed--;
++
+ 	DPRINTK("EXIT\n");
+ 	return 0;
+ }
+ 
+ /**
++ *	ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
++ *	@qc: Storage for translated ATA taskfile
++ *	@scsicmd: SCSI command to translate (ignored)
++ *
++ *	Sets up an ATA taskfile to issue FLUSH CACHE or
++ *	FLUSH CACHE EXT.
++ *
++ *	LOCKING:
++ *	spin_lock_irqsave(host_set lock)
++ *
++ *	RETURNS:
++ *	Zero on success, non-zero on error.
++ */
++
++static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
++{
++	struct ata_taskfile *tf = &qc->tf;
++
++	tf->flags |= ATA_TFLAG_DEVICE;
++	tf->protocol = ATA_PROT_NODATA;
++
++	if ((tf->flags & ATA_TFLAG_LBA48) &&
++	    (ata_id_has_flush_ext(qc->dev->id)))
++		tf->command = ATA_CMD_FLUSH_EXT;
++	else
++		tf->command = ATA_CMD_FLUSH;
++
++	return 0;
++}
++
++/**
++ *	ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
++ *	@qc: Storage for translated ATA taskfile
++ *	@scsicmd: SCSI command to translate
++ *
++ *	Converts SCSI VERIFY command to an ATA READ VERIFY command.
++ *
++ *	LOCKING:
++ *	spin_lock_irqsave(host_set lock)
++ *
++ *	RETURNS:
++ *	Zero on success, non-zero on error.
++ */
++
++static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
++{
++	struct ata_taskfile *tf = &qc->tf;
++	unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
++	u64 dev_sectors = qc->dev->n_sectors;
++	u64 sect = 0;
++	u32 n_sect = 0;
++
++	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
++	tf->protocol = ATA_PROT_NODATA;
++	tf->device |= ATA_LBA;
++
++	if (scsicmd[0] == VERIFY) {
++		sect |= ((u64)scsicmd[2]) << 24;
++		sect |= ((u64)scsicmd[3]) << 16;
++		sect |= ((u64)scsicmd[4]) << 8;
++		sect |= ((u64)scsicmd[5]);
++
++		n_sect |= ((u32)scsicmd[7]) << 8;
++		n_sect |= ((u32)scsicmd[8]);
++	}
++
++	else if (scsicmd[0] == VERIFY_16) {
++		sect |= ((u64)scsicmd[2]) << 56;
++		sect |= ((u64)scsicmd[3]) << 48;
++		sect |= ((u64)scsicmd[4]) << 40;
++		sect |= ((u64)scsicmd[5]) << 32;
++		sect |= ((u64)scsicmd[6]) << 24;
++		sect |= ((u64)scsicmd[7]) << 16;
++		sect |= ((u64)scsicmd[8]) << 8;
++		sect |= ((u64)scsicmd[9]);
++
++		n_sect |= ((u32)scsicmd[10]) << 24;
++		n_sect |= ((u32)scsicmd[11]) << 16;
++		n_sect |= ((u32)scsicmd[12]) << 8;
++		n_sect |= ((u32)scsicmd[13]);
++	}
++
++	else
++		return 1;
++
++	if (!n_sect)
++		return 1;
++	if (sect >= dev_sectors)
++		return 1;
++	if ((sect + n_sect) > dev_sectors)
++		return 1;
++	if (lba48) {
++		if (n_sect > (64 * 1024))
++			return 1;
++	} else {
++		if (n_sect > 256)
++			return 1;
++	}
++
++	if (lba48) {
++		tf->hob_nsect = (n_sect >> 8) & 0xff;
++
++		tf->hob_lbah = (sect >> 40) & 0xff;
++		tf->hob_lbam = (sect >> 32) & 0xff;
++		tf->hob_lbal = (sect >> 24) & 0xff;
++	} else
++		tf->device |= (sect >> 24) & 0xf;
++
++	tf->nsect = n_sect & 0xff;
++
++	tf->hob_lbah = (sect >> 16) & 0xff;
++	tf->hob_lbam = (sect >> 8) & 0xff;
++	tf->hob_lbal = sect & 0xff;
++
++	return 0;
++}
++
++/**
+  *	ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
+  *	@qc: Storage for translated ATA taskfile
+  *	@scsicmd: SCSI command to translate
+@@ -244,10 +530,6 @@
+ 	unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
+ 
+ 	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+-	tf->hob_nsect = 0;
+-	tf->hob_lbal = 0;
+-	tf->hob_lbam = 0;
+-	tf->hob_lbah = 0;
+ 	tf->protocol = qc->dev->xfer_protocol;
+ 	tf->device |= ATA_LBA;
+ 
+@@ -339,14 +621,10 @@
+ {
+ 	struct scsi_cmnd *cmd = qc->scsicmd;
+ 
+-	if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
+-		if (is_atapi_taskfile(&qc->tf))
+-			cmd->result = SAM_STAT_CHECK_CONDITION;
+-		else
+-			ata_to_sense_error(qc);
+-	} else {
++	if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ)))
++		ata_to_sense_error(qc, drv_stat);
++	else
+ 		cmd->result = SAM_STAT_GOOD;
+-	}
+ 
+ 	qc->scsidone(cmd);
+ 
+@@ -401,7 +679,7 @@
+ 			ata_sg_init_one(qc, cmd->request_buffer,
+ 					cmd->request_bufflen);
+ 
+-		qc->pci_dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
++		qc->dma_dir = cmd->sc_data_direction;
+ 	}
+ 
+ 	qc->complete_fn = ata_scsi_qc_complete;
+@@ -451,7 +729,6 @@
+ 		buflen = cmd->request_bufflen;
+ 	}
+ 
+-	memset(buf, 0, buflen);
+ 	*buf_out = buf;
+ 	return buflen;
+ }
+@@ -459,6 +736,7 @@
+ /**
+  *	ata_scsi_rbuf_put - Unmap response buffer.
+  *	@cmd: SCSI command containing buffer to be unmapped.
++ *	@buf: buffer to unmap
+  *
+  *	Unmaps response buffer contained within @cmd.
+  *
+@@ -466,19 +744,19 @@
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd)
++static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
+ {
+ 	if (cmd->use_sg) {
+ 		struct scatterlist *sg;
+ 
+ 		sg = (struct scatterlist *) cmd->request_buffer;
+-		kunmap_atomic(sg->page, KM_USER0);
++		kunmap_atomic(buf - sg->offset, KM_USER0);
+ 	}
+ }
+ 
+ /**
+  *	ata_scsi_rbuf_fill - wrapper for SCSI command simulators
+- *	@args: Port / device / SCSI command of interest.
++ *	@args: device IDENTIFY data / SCSI command of interest.
+  *	@actor: Callback hook for desired SCSI command simulator
+  *
+  *	Takes care of the hard work of simulating a SCSI command...
+@@ -500,8 +778,9 @@
+ 	struct scsi_cmnd *cmd = args->cmd;
+ 
+ 	buflen = ata_scsi_rbuf_get(cmd, &rbuf);
++	memset(rbuf, 0, buflen);
+ 	rc = actor(args, rbuf, buflen);
+-	ata_scsi_rbuf_put(cmd);
++	ata_scsi_rbuf_put(cmd, rbuf);
+ 
+ 	if (rc)
+ 		ata_bad_cdb(cmd, args->done);
+@@ -513,7 +792,7 @@
+ 
+ /**
+  *	ata_scsiop_inq_std - Simulate INQUIRY command
+- *	@args: Port / device / SCSI command of interest.
++ *	@args: device IDENTIFY data / SCSI command of interest.
+  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+  *	@buflen: Response buffer length.
+  *
+@@ -527,28 +806,26 @@
+ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
+ 			       unsigned int buflen)
+ {
+-	struct ata_device *dev = args->dev;
+-
+ 	u8 hdr[] = {
+ 		TYPE_DISK,
+ 		0,
+ 		0x5,	/* claim SPC-3 version compatibility */
+ 		2,
+-		96 - 4
++		95 - 4
+ 	};
+ 
+ 	/* set scsi removeable (RMB) bit per ata bit */
+-	if (ata_id_removeable(dev))
++	if (ata_id_removeable(args->id))
+ 		hdr[1] |= (1 << 7);
+ 
+ 	VPRINTK("ENTER\n");
+ 
+ 	memcpy(rbuf, hdr, sizeof(hdr));
+ 
+-	if (buflen > 36) {
++	if (buflen > 35) {
+ 		memcpy(&rbuf[8], "ATA     ", 8);
+-		ata_dev_id_string(dev, &rbuf[16], ATA_ID_PROD_OFS, 16);
+-		ata_dev_id_string(dev, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
++		ata_dev_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16);
++		ata_dev_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
+ 		if (rbuf[32] == 0 || rbuf[32] == ' ')
+ 			memcpy(&rbuf[32], "n/a ", 4);
+ 	}
+@@ -572,7 +849,7 @@
+ 
+ /**
+  *	ata_scsiop_inq_00 - Simulate INQUIRY EVPD page 0, list of pages
+- *	@args: Port / device / SCSI command of interest.
++ *	@args: device IDENTIFY data / SCSI command of interest.
+  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+  *	@buflen: Response buffer length.
+  *
+@@ -600,7 +877,7 @@
+ 
+ /**
+  *	ata_scsiop_inq_80 - Simulate INQUIRY EVPD page 80, device serial number
+- *	@args: Port / device / SCSI command of interest.
++ *	@args: device IDENTIFY data / SCSI command of interest.
+  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+  *	@buflen: Response buffer length.
+  *
+@@ -621,8 +898,8 @@
+ 	};
+ 	memcpy(rbuf, hdr, sizeof(hdr));
+ 
+-	if (buflen > (ATA_SERNO_LEN + 4))
+-		ata_dev_id_string(args->dev, (unsigned char *) &rbuf[4],
++	if (buflen > (ATA_SERNO_LEN + 4 - 1))
++		ata_dev_id_string(args->id, (unsigned char *) &rbuf[4],
+ 				  ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
+ 
+ 	return 0;
+@@ -632,7 +909,7 @@
+ 
+ /**
+  *	ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity
+- *	@args: Port / device / SCSI command of interest.
++ *	@args: device IDENTIFY data / SCSI command of interest.
+  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+  *	@buflen: Response buffer length.
+  *
+@@ -650,7 +927,7 @@
+ 	rbuf[3] = 4 + strlen(inq_83_str);	/* page len */
+ 
+ 	/* our one and only identification descriptor (vendor-specific) */
+-	if (buflen > (strlen(inq_83_str) + 4 + 4)) {
++	if (buflen > (strlen(inq_83_str) + 4 + 4 - 1)) {
+ 		rbuf[4 + 0] = 2;	/* code set: ASCII */
+ 		rbuf[4 + 3] = strlen(inq_83_str);
+ 		memcpy(rbuf + 4 + 4, inq_83_str, strlen(inq_83_str));
+@@ -661,7 +938,7 @@
+ 
+ /**
+  *	ata_scsiop_noop -
+- *	@args: Port / device / SCSI command of interest.
++ *	@args: device IDENTIFY data / SCSI command of interest.
+  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+  *	@buflen: Response buffer length.
+  *
+@@ -709,7 +986,7 @@
+ 
+ /**
+  *	ata_msense_caching - Simulate MODE SENSE caching info page
+- *	@dev: Device associated with this MODE SENSE command
++ *	@id: device IDENTIFY data
+  *	@ptr_io: (input/output) Location to store more output data
+  *	@last: End of output data buffer
+  *
+@@ -721,7 +998,7 @@
+  *	None.
+  */
+ 
+-static unsigned int ata_msense_caching(struct ata_device *dev, u8 **ptr_io,
++static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io,
+ 				       const u8 *last)
+ {
+ 	u8 page[] = {
+@@ -731,9 +1008,9 @@
+ 		0, 0, 0, 0, 0, 0, 0, 0		/* 8 zeroes */
+ 	};
+ 
+-	if (ata_id_wcache_enabled(dev))
++	if (ata_id_wcache_enabled(id))
+ 		page[2] |= (1 << 2);	/* write cache enable */
+-	if (!ata_id_rahead_enabled(dev))
++	if (!ata_id_rahead_enabled(id))
+ 		page[12] |= (1 << 5);	/* disable read ahead */
+ 
+ 	ata_msense_push(ptr_io, last, page, sizeof(page));
+@@ -787,7 +1064,7 @@
+ 
+ /**
+  *	ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands
+- *	@args: Port / device / SCSI command of interest.
++ *	@args: device IDENTIFY data / SCSI command of interest.
+  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+  *	@buflen: Response buffer length.
+  *
+@@ -801,7 +1078,6 @@
+ 				  unsigned int buflen)
+ {
+ 	u8 *scsicmd = args->cmd->cmnd, *p, *last;
+-	struct ata_device *dev = args->dev;
+ 	unsigned int page_control, six_byte, output_len;
+ 
+ 	VPRINTK("ENTER\n");
+@@ -829,7 +1105,7 @@
+ 		break;
+ 
+ 	case 0x08:		/* caching */
+-		output_len += ata_msense_caching(dev, &p, last);
++		output_len += ata_msense_caching(args->id, &p, last);
+ 		break;
+ 
+ 	case 0x0a: {		/* control mode */
+@@ -839,7 +1115,7 @@
+ 
+ 	case 0x3f:		/* all pages */
+ 		output_len += ata_msense_rw_recovery(&p, last);
+-		output_len += ata_msense_caching(dev, &p, last);
++		output_len += ata_msense_caching(args->id, &p, last);
+ 		output_len += ata_msense_ctl_mode(&p, last);
+ 		break;
+ 
+@@ -861,7 +1137,7 @@
+ 
+ /**
+  *	ata_scsiop_read_cap - Simulate READ CAPACITY[ 16] commands
+- *	@args: Port / device / SCSI command of interest.
++ *	@args: device IDENTIFY data / SCSI command of interest.
+  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+  *	@buflen: Response buffer length.
+  *
+@@ -874,11 +1150,15 @@
+ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
+ 			        unsigned int buflen)
+ {
+-	u64 n_sectors = args->dev->n_sectors;
++	u64 n_sectors;
+ 	u32 tmp;
+ 
+ 	VPRINTK("ENTER\n");
+ 
++	if (ata_id_has_lba48(args->id))
++		n_sectors = ata_id_u64(args->id, 100);
++	else
++		n_sectors = ata_id_u32(args->id, 60);
+ 	n_sectors--;		/* ATA TotalUserSectors - 1 */
+ 
+ 	tmp = n_sectors;	/* note: truncates, if lba48 */
+@@ -916,7 +1196,7 @@
+ 
+ /**
+  *	ata_scsiop_report_luns - Simulate REPORT LUNS command
+- *	@args: Port / device / SCSI command of interest.
++ *	@args: device IDENTIFY data / SCSI command of interest.
+  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+  *	@buflen: Response buffer length.
+  *
+@@ -964,6 +1244,37 @@
+ 	done(cmd);
+ }
+ 
++static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
++{
++	struct scsi_cmnd *cmd = qc->scsicmd;
++
++	if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
++		DPRINTK("request check condition\n");
++
++		cmd->result = SAM_STAT_CHECK_CONDITION;
++
++		qc->scsidone(cmd);
++
++		return 1;
++	} else {
++		u8 *scsicmd = cmd->cmnd;
++
++		if (scsicmd[0] == INQUIRY) {
++			u8 *buf = NULL;
++			unsigned int buflen;
++
++			buflen = ata_scsi_rbuf_get(cmd, &buf);
++			buf[2] = 0x5;
++			buf[3] = (buf[3] & 0xf0) | 2;
++			ata_scsi_rbuf_put(cmd, buf);
++		}
++		cmd->result = SAM_STAT_GOOD;
++	}
++
++	qc->scsidone(cmd);
++
++	return 0;
++}
+ /**
+  *	atapi_xlat - Initialize PACKET taskfile
+  *	@qc: command structure to be initialized
+@@ -979,6 +1290,13 @@
+ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+ {
+ 	struct scsi_cmnd *cmd = qc->scsicmd;
++	struct ata_device *dev = qc->dev;
++	int using_pio = (dev->flags & ATA_DFLAG_PIO);
++	int nodata = (cmd->sc_data_direction == SCSI_DATA_NONE);
++
++	memcpy(&qc->cdb, scsicmd, qc->ap->cdb_len);
++
++	qc->complete_fn = atapi_qc_complete;
+ 
+ 	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ 	if (cmd->sc_data_direction == SCSI_DATA_WRITE) {
+@@ -988,19 +1306,18 @@
+ 
+ 	qc->tf.command = ATA_CMD_PACKET;
+ 
+-	/* no data - interrupt-driven */
+-	if (cmd->sc_data_direction == SCSI_DATA_NONE)
+-		qc->tf.protocol = ATA_PROT_ATAPI;
+-
+-	/* PIO data xfer - polling */
+-	else if ((qc->flags & ATA_QCFLAG_DMA) == 0) {
+-		ata_qc_set_polling(qc);
+-		qc->tf.protocol = ATA_PROT_ATAPI;
++	/* no data, or PIO data xfer */
++	if (using_pio || nodata) {
++		if (nodata)
++			qc->tf.protocol = ATA_PROT_ATAPI_NODATA;
++		else
++			qc->tf.protocol = ATA_PROT_ATAPI;
+ 		qc->tf.lbam = (8 * 1024) & 0xff;
+ 		qc->tf.lbah = (8 * 1024) >> 8;
++	}
+ 
+-	/* DMA data xfer - interrupt-driven */
+-	} else {
++	/* DMA data xfer */
++	else {
+ 		qc->tf.protocol = ATA_PROT_ATAPI_DMA;
+ 		qc->tf.feature |= ATAPI_PKT_DMA;
+ 
+@@ -1011,13 +1328,15 @@
+ #endif
+ 	}
+ 
++	qc->nbytes = cmd->bufflen;
++
+ 	return 0;
+ }
+ 
+ /**
+  *	ata_scsi_find_dev - lookup ata_device from scsi_cmnd
+  *	@ap: ATA port to which the device is attached
+- *	@cmd: SCSI command to be sent to the device
++ *	@scsidev: SCSI device from which we derive the ATA device
+  *
+  *	Given various information provided in struct scsi_cmnd,
+  *	map that onto an ATA bus, and using that mapping
+@@ -1031,19 +1350,19 @@
+  *	Associated ATA device, or %NULL if not found.
+  */
+ 
+-static inline struct ata_device *
+-ata_scsi_find_dev(struct ata_port *ap, struct scsi_cmnd *cmd)
++static struct ata_device *
++ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev)
+ {
+ 	struct ata_device *dev;
+ 
+ 	/* skip commands not addressed to targets we simulate */
+-	if (likely(cmd->device->id < ATA_MAX_DEVICES))
+-		dev = &ap->device[cmd->device->id];
++	if (likely(scsidev->id < ATA_MAX_DEVICES))
++		dev = &ap->device[scsidev->id];
+ 	else
+ 		return NULL;
+ 
+-	if (unlikely((cmd->device->channel != 0) ||
+-		     (cmd->device->lun != 0)))
++	if (unlikely((scsidev->channel != 0) ||
++		     (scsidev->lun != 0)))
+ 		return NULL;
+ 
+ 	if (unlikely(!ata_dev_present(dev)))
+@@ -1059,6 +1378,7 @@
+ 
+ /**
+  *	ata_get_xlat_func - check if SCSI to ATA translation is possible
++ *	@dev: ATA device
+  *	@cmd: SCSI command opcode to consider
+  *
+  *	Look up the SCSI command given, and determine whether the
+@@ -1068,7 +1388,7 @@
+  *	Pointer to translation function if possible, %NULL if not.
+  */
+ 
+-static inline ata_xlat_func_t ata_get_xlat_func(u8 cmd)
++static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
+ {
+ 	switch (cmd) {
+ 	case READ_6:
+@@ -1079,6 +1399,15 @@
+ 	case WRITE_10:
+ 	case WRITE_16:
+ 		return ata_scsi_rw_xlat;
++
++	case SYNCHRONIZE_CACHE:
++		if (ata_try_flush_cache(dev))
++			return ata_scsi_flush_xlat;
++		break;
++
++	case VERIFY:
++	case VERIFY_16:
++		return ata_scsi_verify_xlat;
+ 	}
+ 
+ 	return NULL;
+@@ -1096,11 +1425,12 @@
+ 				     struct scsi_cmnd *cmd)
+ {
+ #ifdef ATA_DEBUG
++	struct scsi_device *scsidev = cmd->device;
+ 	u8 *scsicmd = cmd->cmnd;
+ 
+ 	DPRINTK("CDB (%u:%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ 		ap->id,
+-		cmd->device->channel, cmd->device->id, cmd->device->lun,
++		scsidev->channel, scsidev->id, scsidev->lun,
+ 		scsicmd[0], scsicmd[1], scsicmd[2], scsicmd[3],
+ 		scsicmd[4], scsicmd[5], scsicmd[6], scsicmd[7],
+ 		scsicmd[8]);
+@@ -1130,12 +1460,13 @@
+ {
+ 	struct ata_port *ap;
+ 	struct ata_device *dev;
++	struct scsi_device *scsidev = cmd->device;
+ 
+-	ap = (struct ata_port *) &cmd->device->host->hostdata[0];
++	ap = (struct ata_port *) &scsidev->host->hostdata[0];
+ 
+ 	ata_scsi_dump_cdb(ap, cmd);
+ 
+-	dev = ata_scsi_find_dev(ap, cmd);
++	dev = ata_scsi_find_dev(ap, scsidev);
+ 	if (unlikely(!dev)) {
+ 		cmd->result = (DID_BAD_TARGET << 16);
+ 		done(cmd);
+@@ -1143,12 +1474,13 @@
+ 	}
+ 
+ 	if (dev->class == ATA_DEV_ATA) {
+-		ata_xlat_func_t xlat_func = ata_get_xlat_func(cmd->cmnd[0]);
++		ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
++							      cmd->cmnd[0]);
+ 
+ 		if (xlat_func)
+ 			ata_scsi_translate(ap, dev, cmd, done, xlat_func);
+ 		else
+-			ata_scsi_simulate(ap, dev, cmd, done);
++			ata_scsi_simulate(dev->id, cmd, done);
+ 	} else
+ 		ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
+ 
+@@ -1158,8 +1490,7 @@
+ 
+ /**
+  *	ata_scsi_simulate - simulate SCSI command on ATA device
+- *	@ap: Port to which ATA device is attached.
+- *	@dev: Target device for CDB.
++ *	@id: current IDENTIFY data for target device.
+  *	@cmd: SCSI command being sent to device.
+  *	@done: SCSI command completion function.
+  *
+@@ -1170,21 +1501,20 @@
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
+-			      struct scsi_cmnd *cmd,
+-			      void (*done)(struct scsi_cmnd *))
++void ata_scsi_simulate(u16 *id,
++		      struct scsi_cmnd *cmd,
++		      void (*done)(struct scsi_cmnd *))
+ {
+ 	struct ata_scsi_args args;
+ 	u8 *scsicmd = cmd->cmnd;
+ 
+-	args.ap = ap;
+-	args.dev = dev;
++	args.id = id;
+ 	args.cmd = cmd;
+ 	args.done = done;
+ 
+ 	switch(scsicmd[0]) {
+ 		/* no-op's, complete with success */
+-		case SYNCHRONIZE_CACHE:		/* FIXME: temporary */
++		case SYNCHRONIZE_CACHE:
+ 		case REZERO_UNIT:
+ 		case SEEK_6:
+ 		case SEEK_10:
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/libata.h kernel-source-2.6.8-2.6.8/drivers/scsi/libata.h
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/libata.h	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/libata.h	2006-08-11 14:32:25.352864023 -0600
+@@ -26,12 +26,11 @@
+ #define __LIBATA_H__
+ 
+ #define DRV_NAME	"libata"
+-#define DRV_VERSION	"1.02"	/* must be exactly four chars */
++#define DRV_VERSION	"1.10"	/* must be exactly four chars */
+ 
+ struct ata_scsi_args {
+-	struct ata_port		*ap;
+-	struct ata_device	*dev;
+-	struct scsi_cmnd		*cmd;
++	u16			*id;
++	struct scsi_cmnd	*cmd;
+ 	void			(*done)(struct scsi_cmnd *);
+ };
+ 
+@@ -42,10 +41,11 @@
+ extern void ata_dev_select(struct ata_port *ap, unsigned int device,
+                            unsigned int wait, unsigned int can_sleep);
+ extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf);
++extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
+ 
+ 
+ /* libata-scsi.c */
+-extern void ata_to_sense_error(struct ata_queued_cmd *qc);
++extern void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat);
+ extern int ata_scsi_error(struct Scsi_Host *host);
+ extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
+ 			       unsigned int buflen);
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_nv.c kernel-source-2.6.8-2.6.8/drivers/scsi/sata_nv.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_nv.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/sata_nv.c	2006-08-11 14:32:25.421237630 -0600
+@@ -20,6 +20,10 @@
+  *  If you do not delete the provisions above, a recipient may use your
+  *  version of this file under either the OSL or the GPL.
+  *
++ *  0.03
++ *     - Fixed a bug where the hotplug handlers for non-CK804/MCP04 were using
++ *       mmio_base, which is only set for the CK804/MCP04 case.
++ *
+  *  0.02
+  *     - Added support for CK804 SATA controller.
+  *
+@@ -40,13 +44,12 @@
+ #include <linux/libata.h>
+ 
+ #define DRV_NAME			"sata_nv"
+-#define DRV_VERSION			"0.02"
++#define DRV_VERSION			"0.5"
+ 
+ #define NV_PORTS			2
+ #define NV_PIO_MASK			0x1f
++#define NV_MWDMA_MASK			0x07
+ #define NV_UDMA_MASK			0x7f
+-#define NV_PORT0_BMDMA_REG_OFFSET	0x00
+-#define NV_PORT1_BMDMA_REG_OFFSET	0x08
+ #define NV_PORT0_SCR_REG_OFFSET		0x00
+ #define NV_PORT1_SCR_REG_OFFSET		0x40
+ 
+@@ -177,11 +180,12 @@
+ static Scsi_Host_Template nv_sht = {
+ 	.module			= THIS_MODULE,
+ 	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
+ 	.queuecommand		= ata_scsi_queuecmd,
+ 	.eh_strategy_handler	= ata_scsi_error,
+ 	.can_queue		= ATA_DEF_QUEUE,
+ 	.this_id		= ATA_SHT_THIS_ID,
+-	.sg_tablesize		= ATA_MAX_PRD,
++	.sg_tablesize		= LIBATA_MAX_PRD,
+ 	.max_sectors		= ATA_MAX_SECTORS,
+ 	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
+ 	.emulated		= ATA_SHT_EMULATED,
+@@ -194,13 +198,14 @@
+ 
+ static struct ata_port_operations nv_ops = {
+ 	.port_disable		= ata_port_disable,
+-	.tf_load		= ata_tf_load_pio,
+-	.tf_read		= ata_tf_read_pio,
+-	.exec_command		= ata_exec_command_pio,
+-	.check_status		= ata_check_status_pio,
++	.tf_load		= ata_tf_load,
++	.tf_read		= ata_tf_read,
++	.exec_command		= ata_exec_command,
++	.check_status		= ata_check_status,
++	.dev_select		= ata_std_dev_select,
+ 	.phy_reset		= sata_phy_reset,
+-	.bmdma_setup		= ata_bmdma_setup_pio,
+-	.bmdma_start		= ata_bmdma_start_pio,
++	.bmdma_setup		= ata_bmdma_setup,
++	.bmdma_start		= ata_bmdma_start,
+ 	.qc_prep		= ata_qc_prep,
+ 	.qc_issue		= ata_qc_issue_prot,
+ 	.eng_timeout		= ata_eng_timeout,
+@@ -213,10 +218,31 @@
+ 	.host_stop		= nv_host_stop,
+ };
+ 
++/* FIXME: The hardware provides the necessary SATA PHY controls
++ * to support ATA_FLAG_SATA_RESET.  However, it is currently
++ * necessary to disable that flag, to solve misdetection problems.
++ * See http://bugme.osdl.org/show_bug.cgi?id=3352 for more info.
++ *
++ * This problem really needs to be investigated further.  But in the
++ * meantime, we avoid ATA_FLAG_SATA_RESET to get people working.
++ */
++static struct ata_port_info nv_port_info = {
++	.sht		= &nv_sht,
++	.host_flags	= ATA_FLAG_SATA |
++			  /* ATA_FLAG_SATA_RESET | */
++			  ATA_FLAG_SRST |
++			  ATA_FLAG_NO_LEGACY,
++	.pio_mask	= NV_PIO_MASK,
++	.mwdma_mask	= NV_MWDMA_MASK,
++	.udma_mask	= NV_UDMA_MASK,
++	.port_ops	= &nv_ops,
++};
++
+ MODULE_AUTHOR("NVIDIA");
+ MODULE_DESCRIPTION("low-level driver for NVIDIA nForce SATA controller");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(pci, nv_pci_tbl);
++MODULE_VERSION(DRV_VERSION);
+ 
+ irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+ {
+@@ -293,7 +319,8 @@
+ {
+ 	static int printed_version = 0;
+ 	struct nv_host *host;
+-	struct ata_probe_ent *probe_ent = NULL;
++	struct ata_port_info *ppi;
++	struct ata_probe_ent *probe_ent;
+ 	int rc;
+ 
+ 	if (!printed_version++)
+@@ -301,11 +328,11 @@
+ 
+ 	rc = pci_enable_device(pdev);
+ 	if (rc)
+-		return rc;
++		goto err_out;
+ 
+ 	rc = pci_request_regions(pdev, DRV_NAME);
+ 	if (rc)
+-		goto err_out;
++		goto err_out_disable;
+ 
+ 	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+ 	if (rc)
+@@ -314,53 +341,19 @@
+ 	if (rc)
+ 		goto err_out_regions;
+ 
+-	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+-	if (!probe_ent) {
+-		rc = -ENOMEM;
++	rc = -ENOMEM;
++
++	ppi = &nv_port_info;
++	probe_ent = ata_pci_init_native_mode(pdev, &ppi);
++	if (!probe_ent)
+ 		goto err_out_regions;
+-	}
+ 
+ 	host = kmalloc(sizeof(struct nv_host), GFP_KERNEL);
+-	if (!host) {
+-		rc = -ENOMEM;
++	if (!host)
+ 		goto err_out_free_ent;
+-	}
+ 
+ 	host->host_desc = &nv_device_tbl[ent->driver_data];
+ 
+-	memset(probe_ent, 0, sizeof(*probe_ent));
+-	INIT_LIST_HEAD(&probe_ent->node);
+-
+-	probe_ent->pdev = pdev;
+-	probe_ent->sht = &nv_sht;
+-	probe_ent->host_flags = ATA_FLAG_SATA |
+-				ATA_FLAG_SATA_RESET |
+-				ATA_FLAG_SRST |
+-				ATA_FLAG_NO_LEGACY;
+-
+-	probe_ent->port_ops = &nv_ops;
+-	probe_ent->n_ports = NV_PORTS;
+-	probe_ent->irq = pdev->irq;
+-	probe_ent->irq_flags = SA_SHIRQ;
+-	probe_ent->pio_mask = NV_PIO_MASK;
+-	probe_ent->udma_mask = NV_UDMA_MASK;
+-
+-	probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
+-	ata_std_ports(&probe_ent->port[0]);
+-	probe_ent->port[0].altstatus_addr =
+-	probe_ent->port[0].ctl_addr =
+-		pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
+-	probe_ent->port[0].bmdma_addr =
+-		pci_resource_start(pdev, 4) | NV_PORT0_BMDMA_REG_OFFSET;
+-
+-	probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
+-	ata_std_ports(&probe_ent->port[1]);
+-	probe_ent->port[1].altstatus_addr =
+-	probe_ent->port[1].ctl_addr =
+-		pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
+-	probe_ent->port[1].bmdma_addr =
+-		pci_resource_start(pdev, 4) | NV_PORT1_BMDMA_REG_OFFSET;
+-
+ 	probe_ent->private_data = host;
+ 
+ 	if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO) {
+@@ -368,8 +361,10 @@
+ 
+ 		probe_ent->mmio_base = ioremap(pci_resource_start(pdev, 5),
+ 				pci_resource_len(pdev, 5));
+-		if (probe_ent->mmio_base == NULL)
+-			goto err_out_free_ent;
++		if (probe_ent->mmio_base == NULL) {
++			rc = -EIO;
++			goto err_out_free_host;
++		}
+ 
+ 		base = (unsigned long)probe_ent->mmio_base;
+ 
+@@ -387,26 +382,30 @@
+ 
+ 	pci_set_master(pdev);
+ 
++	rc = ata_device_add(probe_ent);
++	if (rc != NV_PORTS)
++		goto err_out_iounmap;
++
+ 	// Enable hotplug event interrupts.
+ 	if (host->host_desc->enable_hotplug)
+ 		host->host_desc->enable_hotplug(probe_ent);
+ 
+-	rc = ata_device_add(probe_ent);
+-	if (rc != NV_PORTS)
+-		goto err_out_free_ent;
+-
+ 	kfree(probe_ent);
+ 
+ 	return 0;
+ 
++err_out_iounmap:
++	if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO)
++		iounmap(probe_ent->mmio_base);
++err_out_free_host:
++	kfree(host);
+ err_out_free_ent:
+ 	kfree(probe_ent);
+-
+ err_out_regions:
+ 	pci_release_regions(pdev);
+-
+-err_out:
++err_out_disable:
+ 	pci_disable_device(pdev);
++err_out:
+ 	return rc;
+ }
+ 
+@@ -415,33 +414,33 @@
+ 	u8 intr_mask;
+ 
+ 	outb(NV_INT_STATUS_HOTPLUG,
+-		(unsigned long)probe_ent->mmio_base + NV_INT_STATUS);
++		probe_ent->port[0].scr_addr + NV_INT_STATUS);
+ 
+-	intr_mask = inb((unsigned long)probe_ent->mmio_base + NV_INT_ENABLE);
++	intr_mask = inb(probe_ent->port[0].scr_addr + NV_INT_ENABLE);
+ 	intr_mask |= NV_INT_ENABLE_HOTPLUG;
+ 
+-	outb(intr_mask, (unsigned long)probe_ent->mmio_base + NV_INT_ENABLE);
++	outb(intr_mask, probe_ent->port[0].scr_addr + NV_INT_ENABLE);
+ }
+ 
+ static void nv_disable_hotplug(struct ata_host_set *host_set)
+ {
+ 	u8 intr_mask;
+ 
+-	intr_mask = inb((unsigned long)host_set->mmio_base + NV_INT_ENABLE);
++	intr_mask = inb(host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE);
+ 
+ 	intr_mask &= ~(NV_INT_ENABLE_HOTPLUG);
+ 
+-	outb(intr_mask, (unsigned long)host_set->mmio_base + NV_INT_ENABLE);
++	outb(intr_mask, host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE);
+ }
+ 
+ static void nv_check_hotplug(struct ata_host_set *host_set)
+ {
+ 	u8 intr_status;
+ 
+-	intr_status = inb((unsigned long)host_set->mmio_base + NV_INT_STATUS);
++	intr_status = inb(host_set->ports[0]->ioaddr.scr_addr + NV_INT_STATUS);
+ 
+ 	// Clear interrupt status.
+-	outb(0xff, (unsigned long)host_set->mmio_base + NV_INT_STATUS);
++	outb(0xff, host_set->ports[0]->ioaddr.scr_addr + NV_INT_STATUS);
+ 
+ 	if (intr_status & NV_INT_STATUS_HOTPLUG) {
+ 		if (intr_status & NV_INT_STATUS_PDEV_ADDED)
+@@ -464,12 +463,13 @@
+ 
+ static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent)
+ {
++	struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
+ 	u8 intr_mask;
+ 	u8 regval;
+ 
+-	pci_read_config_byte(probe_ent->pdev, NV_MCP_SATA_CFG_20, &regval);
++	pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
+ 	regval |= NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
+-	pci_write_config_byte(probe_ent->pdev, NV_MCP_SATA_CFG_20, regval);
++	pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
+ 
+ 	writeb(NV_INT_STATUS_HOTPLUG, probe_ent->mmio_base + NV_INT_STATUS_CK804);
+ 
+@@ -481,6 +481,7 @@
+ 
+ static void nv_disable_hotplug_ck804(struct ata_host_set *host_set)
+ {
++	struct pci_dev *pdev = to_pci_dev(host_set->dev);
+ 	u8 intr_mask;
+ 	u8 regval;
+ 
+@@ -490,9 +491,9 @@
+ 
+ 	writeb(intr_mask, host_set->mmio_base + NV_INT_ENABLE_CK804);
+ 
+-	pci_read_config_byte(host_set->pdev, NV_MCP_SATA_CFG_20, &regval);
++	pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
+ 	regval &= ~NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
+-	pci_write_config_byte(host_set->pdev, NV_MCP_SATA_CFG_20, regval);
++	pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
+ }
+ 
+ static void nv_check_hotplug_ck804(struct ata_host_set *host_set)
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_promise.c kernel-source-2.6.8-2.6.8/drivers/scsi/sata_promise.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_promise.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/sata_promise.c	2006-08-11 14:32:25.354817554 -0600
+@@ -40,7 +40,7 @@
+ #include "sata_promise.h"
+ 
+ #define DRV_NAME	"sata_promise"
+-#define DRV_VERSION	"1.00"
++#define DRV_VERSION	"1.01"
+ 
+ 
+ enum {
+@@ -73,8 +73,7 @@
+ 
+ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
+ static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
+-static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+-static void pdc_dma_start(struct ata_queued_cmd *qc);
++static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+ static void pdc_eng_timeout(struct ata_port *ap);
+ static int pdc_port_start(struct ata_port *ap);
+@@ -83,14 +82,13 @@
+ static void pdc_qc_prep(struct ata_queued_cmd *qc);
+ static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+ static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+-static inline void pdc_dma_complete (struct ata_port *ap,
+-                                     struct ata_queued_cmd *qc, int have_err);
+ static void pdc_irq_clear(struct ata_port *ap);
+ static int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
+ 
+-static Scsi_Host_Template pdc_sata_sht = {
++static Scsi_Host_Template pdc_ata_sht = {
+ 	.module			= THIS_MODULE,
+ 	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
+ 	.queuecommand		= ata_scsi_queuecmd,
+ 	.eh_strategy_handler	= ata_scsi_error,
+ 	.can_queue		= ATA_DEF_QUEUE,
+@@ -106,12 +104,13 @@
+ 	.bios_param		= ata_std_bios_param,
+ };
+ 
+-static struct ata_port_operations pdc_sata_ops = {
++static struct ata_port_operations pdc_ata_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.tf_load		= pdc_tf_load_mmio,
+-	.tf_read		= ata_tf_read_mmio,
+-	.check_status		= ata_check_status_mmio,
++	.tf_read		= ata_tf_read,
++	.check_status		= ata_check_status,
+ 	.exec_command		= pdc_exec_command_mmio,
++	.dev_select		= ata_std_dev_select,
+ 	.phy_reset		= pdc_phy_reset,
+ 	.qc_prep		= pdc_qc_prep,
+ 	.qc_issue		= pdc_qc_issue_prot,
+@@ -127,26 +126,28 @@
+ static struct ata_port_info pdc_port_info[] = {
+ 	/* board_2037x */
+ 	{
+-		.sht		= &pdc_sata_sht,
++		.sht		= &pdc_ata_sht,
+ 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ 				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
+-		.pio_mask	= 0x03, /* pio3-4 */
++		.pio_mask	= 0x1f, /* pio0-4 */
++		.mwdma_mask	= 0x07, /* mwdma0-2 */
+ 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
+-		.port_ops	= &pdc_sata_ops,
++		.port_ops	= &pdc_ata_ops,
+ 	},
+ 
+ 	/* board_20319 */
+ 	{
+-		.sht		= &pdc_sata_sht,
++		.sht		= &pdc_ata_sht,
+ 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ 				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
+-		.pio_mask	= 0x03, /* pio3-4 */
++		.pio_mask	= 0x1f, /* pio0-4 */
++		.mwdma_mask	= 0x07, /* mwdma0-2 */
+ 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
+-		.port_ops	= &pdc_sata_ops,
++		.port_ops	= &pdc_ata_ops,
+ 	},
+ };
+ 
+-static struct pci_device_id pdc_sata_pci_tbl[] = {
++static struct pci_device_id pdc_ata_pci_tbl[] = {
+ 	{ PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 	  board_2037x },
+ 	{ PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+@@ -163,17 +164,17 @@
+ };
+ 
+ 
+-static struct pci_driver pdc_sata_pci_driver = {
++static struct pci_driver pdc_ata_pci_driver = {
+ 	.name			= DRV_NAME,
+-	.id_table		= pdc_sata_pci_tbl,
+-	.probe			= pdc_sata_init_one,
++	.id_table		= pdc_ata_pci_tbl,
++	.probe			= pdc_ata_init_one,
+ 	.remove			= ata_pci_remove_one,
+ };
+ 
+ 
+ static int pdc_port_start(struct ata_port *ap)
+ {
+-	struct pci_dev *pdev = ap->host_set->pdev;
++	struct device *dev = ap->host_set->dev;
+ 	struct pdc_port_priv *pp;
+ 	int rc;
+ 
+@@ -188,7 +189,7 @@
+ 	}
+ 	memset(pp, 0, sizeof(*pp));
+ 
+-	pp->pkt = pci_alloc_consistent(pdev, 128, &pp->pkt_dma);
++	pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
+ 	if (!pp->pkt) {
+ 		rc = -ENOMEM;
+ 		goto err_out_kfree;
+@@ -208,11 +209,11 @@
+ 
+ static void pdc_port_stop(struct ata_port *ap)
+ {
+-	struct pci_dev *pdev = ap->host_set->pdev;
++	struct device *dev = ap->host_set->dev;
+ 	struct pdc_port_priv *pp = ap->private_data;
+ 
+ 	ap->private_data = NULL;
+-	pci_free_consistent(pdev, 128, pp->pkt, pp->pkt_dma);
++	dma_free_coherent(dev, 128, pp->pkt, pp->pkt_dma);
+ 	kfree(pp);
+ 	ata_port_stop(ap);
+ }
+@@ -269,26 +270,26 @@
+ 
+ 	VPRINTK("ENTER\n");
+ 
+-	ata_qc_prep(qc);
+-
+-	i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma,  qc->dev->devno, pp->pkt);
++	switch (qc->tf.protocol) {
++	case ATA_PROT_DMA:
++		ata_qc_prep(qc);
++		/* fall through */
+ 
+-	if (qc->tf.flags & ATA_TFLAG_LBA48)
+-		i = pdc_prep_lba48(&qc->tf, pp->pkt, i);
+-	else
+-		i = pdc_prep_lba28(&qc->tf, pp->pkt, i);
++	case ATA_PROT_NODATA:
++		i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma,
++				   qc->dev->devno, pp->pkt);
+ 
+-	pdc_pkt_footer(&qc->tf, pp->pkt, i);
+-}
++		if (qc->tf.flags & ATA_TFLAG_LBA48)
++			i = pdc_prep_lba48(&qc->tf, pp->pkt, i);
++		else
++			i = pdc_prep_lba28(&qc->tf, pp->pkt, i);
+ 
+-static inline void pdc_dma_complete (struct ata_port *ap,
+-                                     struct ata_queued_cmd *qc,
+-				     int have_err)
+-{
+-	u8 err_bit = have_err ? ATA_ERR : 0;
++		pdc_pkt_footer(&qc->tf, pp->pkt, i);
++		break;
+ 
+-	/* get drive status; clear intr; complete txn */
+-	ata_qc_complete(qc, ata_wait_idle(ap) | err_bit);
++	default:
++		break;
++	}
+ }
+ 
+ static void pdc_eng_timeout(struct ata_port *ap)
+@@ -315,17 +316,9 @@
+ 
+ 	switch (qc->tf.protocol) {
+ 	case ATA_PROT_DMA:
+-		printk(KERN_ERR "ata%u: DMA timeout\n", ap->id);
+-		ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
+-		break;
+-
+ 	case ATA_PROT_NODATA:
+-		drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+-
+-		printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x\n",
+-		       ap->id, qc->tf.command, drv_stat);
+-
+-		ata_qc_complete(qc, drv_stat);
++		printk(KERN_ERR "ata%u: command timeout\n", ap->id);
++		ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
+ 		break;
+ 
+ 	default:
+@@ -358,13 +351,8 @@
+ 
+ 	switch (qc->tf.protocol) {
+ 	case ATA_PROT_DMA:
+-		pdc_dma_complete(ap, qc, have_err);
+-		handled = 1;
+-		break;
+-
+-	case ATA_PROT_NODATA:   /* command completion, but no data xfer */
+-		status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+-		DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
++	case ATA_PROT_NODATA:
++		status = ata_wait_idle(ap);
+ 		if (have_err)
+ 			status |= ATA_ERR;
+ 		ata_qc_complete(qc, status);
+@@ -440,7 +428,7 @@
+ 	return IRQ_RETVAL(handled);
+ }
+ 
+-static inline void pdc_dma_start(struct ata_queued_cmd *qc)
++static inline void pdc_packet_start(struct ata_queued_cmd *qc)
+ {
+ 	struct ata_port *ap = qc->ap;
+ 	struct pdc_port_priv *pp = ap->private_data;
+@@ -462,7 +450,8 @@
+ {
+ 	switch (qc->tf.protocol) {
+ 	case ATA_PROT_DMA:
+-		pdc_dma_start(qc);
++	case ATA_PROT_NODATA:
++		pdc_packet_start(qc);
+ 		return 0;
+ 
+ 	case ATA_PROT_ATAPI_DMA:
+@@ -478,19 +467,21 @@
+ 
+ static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+-	WARN_ON (tf->protocol == ATA_PROT_DMA);
+-	ata_tf_load_mmio(ap, tf);
++	WARN_ON (tf->protocol == ATA_PROT_DMA ||
++		 tf->protocol == ATA_PROT_NODATA);
++	ata_tf_load(ap, tf);
+ }
+ 
+ 
+ static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+-	WARN_ON (tf->protocol == ATA_PROT_DMA);
+-	ata_exec_command_mmio(ap, tf);
++	WARN_ON (tf->protocol == ATA_PROT_DMA ||
++		 tf->protocol == ATA_PROT_NODATA);
++	ata_exec_command(ap, tf);
+ }
+ 
+ 
+-static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base)
++static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
+ {
+ 	port->cmd_addr		= base;
+ 	port->data_addr		= base;
+@@ -539,8 +530,7 @@
+ 	writel(tmp, mmio + PDC_TBG_MODE);
+ 
+ 	readl(mmio + PDC_TBG_MODE);	/* flush */
+-	set_current_state(TASK_UNINTERRUPTIBLE);
+-	schedule_timeout(msecs_to_jiffies(10) + 1);
++	msleep(10);
+ 
+ 	/* adjust slew rate control register. */
+ 	tmp = readl(mmio + PDC_SLEW_CTL);
+@@ -549,7 +539,7 @@
+ 	writel(tmp, mmio + PDC_SLEW_CTL);
+ }
+ 
+-static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
++static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+ 	static int printed_version;
+ 	struct ata_probe_ent *probe_ent = NULL;
+@@ -587,7 +577,7 @@
+ 	}
+ 
+ 	memset(probe_ent, 0, sizeof(*probe_ent));
+-	probe_ent->pdev = pdev;
++	probe_ent->dev = pci_dev_to_dev(pdev);
+ 	INIT_LIST_HEAD(&probe_ent->node);
+ 
+ 	mmio_base = ioremap(pci_resource_start(pdev, 3),
+@@ -601,6 +591,7 @@
+ 	probe_ent->sht		= pdc_port_info[board_idx].sht;
+ 	probe_ent->host_flags	= pdc_port_info[board_idx].host_flags;
+ 	probe_ent->pio_mask	= pdc_port_info[board_idx].pio_mask;
++	probe_ent->mwdma_mask	= pdc_port_info[board_idx].mwdma_mask;
+ 	probe_ent->udma_mask	= pdc_port_info[board_idx].udma_mask;
+ 	probe_ent->port_ops	= pdc_port_info[board_idx].port_ops;
+ 
+@@ -608,8 +599,8 @@
+        	probe_ent->irq_flags = SA_SHIRQ;
+ 	probe_ent->mmio_base = mmio_base;
+ 
+-	pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
+-	pdc_sata_setup_port(&probe_ent->port[1], base + 0x280);
++	pdc_ata_setup_port(&probe_ent->port[0], base + 0x200);
++	pdc_ata_setup_port(&probe_ent->port[1], base + 0x280);
+ 
+ 	probe_ent->port[0].scr_addr = base + 0x400;
+ 	probe_ent->port[1].scr_addr = base + 0x500;
+@@ -619,8 +610,8 @@
+ 	case board_20319:
+        		probe_ent->n_ports = 4;
+ 
+-		pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
+-		pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
++		pdc_ata_setup_port(&probe_ent->port[2], base + 0x300);
++		pdc_ata_setup_port(&probe_ent->port[3], base + 0x380);
+ 
+ 		probe_ent->port[2].scr_addr = base + 0x600;
+ 		probe_ent->port[3].scr_addr = base + 0x700;
+@@ -654,22 +645,23 @@
+ }
+ 
+ 
+-static int __init pdc_sata_init(void)
++static int __init pdc_ata_init(void)
+ {
+-	return pci_module_init(&pdc_sata_pci_driver);
++	return pci_module_init(&pdc_ata_pci_driver);
+ }
+ 
+ 
+-static void __exit pdc_sata_exit(void)
++static void __exit pdc_ata_exit(void)
+ {
+-	pci_unregister_driver(&pdc_sata_pci_driver);
++	pci_unregister_driver(&pdc_ata_pci_driver);
+ }
+ 
+ 
+ MODULE_AUTHOR("Jeff Garzik");
+ MODULE_DESCRIPTION("Promise SATA TX2/TX4 low-level driver");
+ MODULE_LICENSE("GPL");
+-MODULE_DEVICE_TABLE(pci, pdc_sata_pci_tbl);
++MODULE_DEVICE_TABLE(pci, pdc_ata_pci_tbl);
++MODULE_VERSION(DRV_VERSION);
+ 
+-module_init(pdc_sata_init);
+-module_exit(pdc_sata_exit);
++module_init(pdc_ata_init);
++module_exit(pdc_ata_exit);
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_sil.c kernel-source-2.6.8-2.6.8/drivers/scsi/sata_sil.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_sil.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/sata_sil.c	2006-08-11 14:32:25.355794320 -0600
+@@ -6,7 +6,7 @@
+  *		    on emails.
+  *
+  *  Copyright 2003 Red Hat, Inc.
+- *  Copyright 2003 Benjamin Herrenschmidt <benh at kernel.crashing.org>
++ *  Copyright 2003 Benjamin Herrenschmidt
+  *
+  *  The contents of this file are subject to the Open
+  *  Software License version 1.1 that can be found at
+@@ -38,7 +38,7 @@
+ #include <linux/libata.h>
+ 
+ #define DRV_NAME	"sata_sil"
+-#define DRV_VERSION	"0.54"
++#define DRV_VERSION	"0.8"
+ 
+ enum {
+ 	sil_3112		= 0,
+@@ -87,6 +87,7 @@
+ 	{ "ST380023AS",		SIL_QUIRK_MOD15WRITE },
+ 	{ "ST3120023AS",	SIL_QUIRK_MOD15WRITE },
+ 	{ "ST3160023AS",	SIL_QUIRK_MOD15WRITE },
++	{ "ST3120026AS",	SIL_QUIRK_MOD15WRITE },
+ 	{ "ST340014ASL",	SIL_QUIRK_MOD15WRITE },
+ 	{ "ST360014ASL",	SIL_QUIRK_MOD15WRITE },
+ 	{ "ST380011ASL",	SIL_QUIRK_MOD15WRITE },
+@@ -106,6 +107,7 @@
+ static Scsi_Host_Template sil_sht = {
+ 	.module			= THIS_MODULE,
+ 	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
+ 	.queuecommand		= ata_scsi_queuecmd,
+ 	.eh_strategy_handler	= ata_scsi_error,
+ 	.can_queue		= ATA_DEF_QUEUE,
+@@ -124,14 +126,15 @@
+ static struct ata_port_operations sil_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.dev_config		= sil_dev_config,
+-	.tf_load		= ata_tf_load_mmio,
+-	.tf_read		= ata_tf_read_mmio,
+-	.check_status		= ata_check_status_mmio,
+-	.exec_command		= ata_exec_command_mmio,
++	.tf_load		= ata_tf_load,
++	.tf_read		= ata_tf_read,
++	.check_status		= ata_check_status,
++	.exec_command		= ata_exec_command,
++	.dev_select		= ata_std_dev_select,
+ 	.phy_reset		= sata_phy_reset,
+ 	.post_set_mode		= sil_post_set_mode,
+-	.bmdma_setup            = ata_bmdma_setup_mmio,
+-	.bmdma_start            = ata_bmdma_start_mmio,
++	.bmdma_setup            = ata_bmdma_setup,
++	.bmdma_start            = ata_bmdma_start,
+ 	.qc_prep		= ata_qc_prep,
+ 	.qc_issue		= ata_qc_issue_prot,
+ 	.eng_timeout		= ata_eng_timeout,
+@@ -149,7 +152,8 @@
+ 		.sht		= &sil_sht,
+ 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ 				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
+-		.pio_mask	= 0x03,			/* pio3-4 */
++		.pio_mask	= 0x1f,			/* pio0-4 */
++		.mwdma_mask	= 0x07,			/* mwdma0-2 */
+ 		.udma_mask	= 0x3f,			/* udma0-5 */
+ 		.port_ops	= &sil_ops,
+ 	}, /* sil_3114 */
+@@ -157,7 +161,8 @@
+ 		.sht		= &sil_sht,
+ 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ 				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
+-		.pio_mask	= 0x03,			/* pio3-4 */
++		.pio_mask	= 0x1f,			/* pio0-4 */
++		.mwdma_mask	= 0x07,			/* mwdma0-2 */
+ 		.udma_mask	= 0x3f,			/* udma0-5 */
+ 		.port_ops	= &sil_ops,
+ 	},
+@@ -185,6 +190,7 @@
+ MODULE_DESCRIPTION("low-level driver for Silicon Image SATA controller");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(pci, sil_pci_tbl);
++MODULE_VERSION(DRV_VERSION);
+ 
+ static void sil_post_set_mode (struct ata_port *ap)
+ {
+@@ -283,7 +289,7 @@
+ 	const char *s;
+ 	unsigned int len;
+ 
+-	ata_dev_id_string(dev, model_num, ATA_ID_PROD_OFS,
++	ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
+ 			  sizeof(model_num));
+ 	s = &model_num[0];
+ 	len = strnlen(s, sizeof(model_num));
+@@ -358,11 +364,12 @@
+ 
+ 	memset(probe_ent, 0, sizeof(*probe_ent));
+ 	INIT_LIST_HEAD(&probe_ent->node);
+-	probe_ent->pdev = pdev;
++	probe_ent->dev = pci_dev_to_dev(pdev);
+ 	probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops;
+ 	probe_ent->sht = sil_port_info[ent->driver_data].sht;
+ 	probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2;
+ 	probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask;
++	probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask;
+ 	probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask;
+        	probe_ent->irq = pdev->irq;
+        	probe_ent->irq_flags = SA_SHIRQ;
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_sis.c kernel-source-2.6.8-2.6.8/drivers/scsi/sata_sis.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_sis.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/sata_sis.c	2006-08-11 14:32:25.355794320 -0600
+@@ -38,7 +38,7 @@
+ #include <linux/libata.h>
+ 
+ #define DRV_NAME	"sata_sis"
+-#define DRV_VERSION	"0.10"
++#define DRV_VERSION	"0.5"
+ 
+ enum {
+ 	sis_180			= 0,
+@@ -76,6 +76,7 @@
+ static Scsi_Host_Template sis_sht = {
+ 	.module			= THIS_MODULE,
+ 	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
+ 	.queuecommand		= ata_scsi_queuecmd,
+ 	.eh_strategy_handler	= ata_scsi_error,
+ 	.can_queue		= ATA_DEF_QUEUE,
+@@ -93,13 +94,14 @@
+ 
+ static struct ata_port_operations sis_ops = {
+ 	.port_disable		= ata_port_disable,
+-	.tf_load		= ata_tf_load_pio,
+-	.tf_read		= ata_tf_read_pio,
+-	.check_status		= ata_check_status_pio,
+-	.exec_command		= ata_exec_command_pio,
++	.tf_load		= ata_tf_load,
++	.tf_read		= ata_tf_read,
++	.check_status		= ata_check_status,
++	.exec_command		= ata_exec_command,
++	.dev_select		= ata_std_dev_select,
+ 	.phy_reset		= sata_phy_reset,
+-	.bmdma_setup            = ata_bmdma_setup_pio,
+-	.bmdma_start            = ata_bmdma_start_pio,
++	.bmdma_setup            = ata_bmdma_setup,
++	.bmdma_start            = ata_bmdma_start,
+ 	.qc_prep		= ata_qc_prep,
+ 	.qc_issue		= ata_qc_issue_prot,
+ 	.eng_timeout		= ata_eng_timeout,
+@@ -111,11 +113,22 @@
+ 	.port_stop		= ata_port_stop,
+ };
+ 
++static struct ata_port_info sis_port_info = {
++	.sht		= &sis_sht,
++	.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
++			  ATA_FLAG_NO_LEGACY,
++	.pio_mask	= 0x1f,
++	.mwdma_mask	= 0x7,
++	.udma_mask	= 0x7f,
++	.port_ops	= &sis_ops,
++};
++
+ 
+ MODULE_AUTHOR("Uwe Koziolek");
+ MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
++MODULE_VERSION(DRV_VERSION);
+ 
+ static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg)
+ {
+@@ -128,22 +141,24 @@
+ 
+ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
+ {
++	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+ 	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg);
+ 	u32 val;
+ 
+ 	if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
+ 		return 0xffffffff;
+-	pci_read_config_dword(ap->host_set->pdev, cfg_addr, &val);
++	pci_read_config_dword(pdev, cfg_addr, &val);
+ 	return val;
+ }
+ 
+ static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
+ {
++	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+ 	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr);
+ 
+ 	if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */
+ 		return;
+-	pci_write_config_dword(ap->host_set->pdev, cfg_addr, val);
++	pci_write_config_dword(pdev, cfg_addr, val);
+ }
+ 
+ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
+@@ -184,6 +199,7 @@
+ 	struct ata_probe_ent *probe_ent = NULL;
+ 	int rc;
+ 	u32 genctl;
++	struct ata_port_info *ppi;
+ 
+ 	rc = pci_enable_device(pdev);
+ 	if (rc)
+@@ -200,20 +216,13 @@
+ 	if (rc)
+ 		goto err_out_regions;
+ 
+-	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
++	ppi = &sis_port_info;
++	probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+ 	if (!probe_ent) {
+ 		rc = -ENOMEM;
+ 		goto err_out_regions;
+ 	}
+ 
+-	memset(probe_ent, 0, sizeof(*probe_ent));
+-	probe_ent->pdev = pdev;
+-	INIT_LIST_HEAD(&probe_ent->node);
+-
+-	probe_ent->sht = &sis_sht;
+-	probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
+-				ATA_FLAG_NO_LEGACY;
+-
+ 	/* check and see if the SCRs are in IO space or PCI cfg space */
+ 	pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
+ 	if ((genctl & GENCTL_IOMAPPED_SCR) == 0)
+@@ -230,31 +239,12 @@
+ 		probe_ent->host_flags |= SIS_FLAG_CFGSCR;
+ 	}
+ 
+-	probe_ent->pio_mask = 0x03;
+-	probe_ent->udma_mask = 0x7f;
+-	probe_ent->port_ops = &sis_ops;
+-
+-	probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
+-	ata_std_ports(&probe_ent->port[0]);
+-	probe_ent->port[0].ctl_addr =
+-		pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
+-	probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
+-	if (!(probe_ent->host_flags & SIS_FLAG_CFGSCR))
++	if (!(probe_ent->host_flags & SIS_FLAG_CFGSCR)) {
+ 		probe_ent->port[0].scr_addr =
+ 			pci_resource_start(pdev, SIS_SCR_PCI_BAR);
+-
+-	probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
+-	ata_std_ports(&probe_ent->port[1]);
+-	probe_ent->port[1].ctl_addr =
+-		pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
+-	probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
+-	if (!(probe_ent->host_flags & SIS_FLAG_CFGSCR))
+ 		probe_ent->port[1].scr_addr =
+ 			pci_resource_start(pdev, SIS_SCR_PCI_BAR) + 64;
+-
+-	probe_ent->n_ports = 2;
+-	probe_ent->irq = pdev->irq;
+-	probe_ent->irq_flags = SA_SHIRQ;
++	}
+ 
+ 	pci_set_master(pdev);
+ 	pci_enable_intx(pdev);
+@@ -284,6 +274,6 @@
+ 	pci_unregister_driver(&sis_pci_driver);
+ }
+ 
+-
+ module_init(sis_init);
+ module_exit(sis_exit);
++
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_svw.c kernel-source-2.6.8-2.6.8/drivers/scsi/sata_svw.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_svw.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/sata_svw.c	2006-08-11 14:32:25.367515510 -0600
+@@ -49,7 +49,7 @@
+ #endif /* CONFIG_PPC_OF */
+ 
+ #define DRV_NAME	"sata_svw"
+-#define DRV_VERSION	"1.04"
++#define DRV_VERSION	"1.05"
+ 
+ /* Taskfile registers offsets */
+ #define K2_SATA_TF_CMD_OFFSET		0x00
+@@ -148,7 +148,73 @@
+         }
+ }
+ 
++/**
++ *	k2_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction (MMIO)
++ *	@qc: Info associated with this ATA transaction.
++ *
++ *	LOCKING:
++ *	spin_lock_irqsave(host_set lock)
++ */
++
++void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
++{
++	struct ata_port *ap = qc->ap;
++	unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
++	u8 dmactl;
++	void *mmio = (void *) ap->ioaddr.bmdma_addr;
++	/* load PRD table addr. */
++	mb();	/* make sure PRD table writes are visible to controller */
++	writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);
++
++	/* specify data direction, triple-check start bit is clear */
++	dmactl = readb(mmio + ATA_DMA_CMD);
++	dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
++	if (!rw)
++		dmactl |= ATA_DMA_WR;
++	writeb(dmactl, mmio + ATA_DMA_CMD);
++
++	/* issue r/w command if this is not a ATA DMA command*/
++	if (qc->tf.protocol != ATA_PROT_DMA)
++		ap->ops->exec_command(ap, &qc->tf);
++}
++
++/**
++ *	k2_bmdma_start_mmio - Start a PCI IDE BMDMA transaction (MMIO)
++ *	@qc: Info associated with this ATA transaction.
++ *
++ *	LOCKING:
++ *	spin_lock_irqsave(host_set lock)
++ */
+ 
++void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
++{
++	struct ata_port *ap = qc->ap;
++	void *mmio = (void *) ap->ioaddr.bmdma_addr;
++	u8 dmactl;
++
++	/* start host DMA transaction */
++	dmactl = readb(mmio + ATA_DMA_CMD);
++	writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD);
++	/* There is a race condition in certain SATA controllers that can 
++	   be seen when the r/w command is given to the controller before the 
++	   host DMA is started. On a Read command, the controller would initiate
++	   the command to the drive even before it sees the DMA start. When there
++	   are very fast drives connected to the controller, or when the data request 
++	   hits in the drive cache, there is the possibility that the drive returns a part
++	   or all of the requested data to the controller before the DMA start is issued.
++	   In this case, the controller would become confused as to what to do with the data.
++	   In the worst case when all the data is returned back to the controller, the
++	   controller could hang. In other cases it could return partial data returning
++	   in data corruption. This problem has been seen in PPC systems and can also appear
++	   on an system with very fast disks, where the SATA controller is sitting behind a 
++	   number of bridges, and hence there is significant latency between the r/w command
++	   and the start command. */
++	/* issue r/w command if the access is to ATA*/
++	if (qc->tf.protocol == ATA_PROT_DMA)
++		ap->ops->exec_command(ap, &qc->tf);
++}
++
++									      
+ static u8 k2_stat_check_status(struct ata_port *ap)
+ {
+        	return readl((void *) ap->ioaddr.status_addr);
+@@ -179,7 +245,7 @@
+ 		return 0;
+ 
+ 	/* Find the OF node for the PCI device proper */
+-	np = pci_device_to_OF_node(ap->host_set->pdev);
++	np = pci_device_to_OF_node(to_pci_dev(ap->host_set->dev));
+ 	if (np == NULL)
+ 		return 0;
+ 
+@@ -205,6 +271,7 @@
+ static Scsi_Host_Template k2_sata_sht = {
+ 	.module			= THIS_MODULE,
+ 	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
+ 	.queuecommand		= ata_scsi_queuecmd,
+ 	.eh_strategy_handler	= ata_scsi_error,
+ 	.can_queue		= ATA_DEF_QUEUE,
+@@ -229,10 +296,11 @@
+ 	.tf_load		= k2_sata_tf_load,
+ 	.tf_read		= k2_sata_tf_read,
+ 	.check_status		= k2_stat_check_status,
+-	.exec_command		= ata_exec_command_mmio,
++	.exec_command		= ata_exec_command,
++	.dev_select		= ata_std_dev_select,
+ 	.phy_reset		= sata_phy_reset,
+-	.bmdma_setup            = ata_bmdma_setup_mmio,
+-	.bmdma_start            = ata_bmdma_start_mmio,
++	.bmdma_setup		= k2_bmdma_setup_mmio,
++	.bmdma_start		= k2_bmdma_start_mmio,
+ 	.qc_prep		= ata_qc_prep,
+ 	.qc_issue		= ata_qc_issue_prot,
+ 	.eng_timeout		= ata_eng_timeout,
+@@ -308,7 +376,7 @@
+ 	}
+ 
+ 	memset(probe_ent, 0, sizeof(*probe_ent));
+-	probe_ent->pdev = pdev;
++	probe_ent->dev = pci_dev_to_dev(pdev);
+ 	INIT_LIST_HEAD(&probe_ent->node);
+ 
+ 	mmio_base = ioremap(pci_resource_start(pdev, 5),
+@@ -343,6 +411,7 @@
+ 	 * if we don't fill these
+ 	 */
+ 	probe_ent->pio_mask = 0x1f;
++	probe_ent->mwdma_mask = 0x7;
+ 	probe_ent->udma_mask = 0x7f;
+ 
+ 	/* We have 4 ports per PCI function */
+@@ -371,6 +440,8 @@
+ 
+ static struct pci_device_id k2_sata_pci_tbl[] = {
+ 	{ 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
++	{ 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
++	{ 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ 	{ }
+ };
+ 
+@@ -388,6 +459,7 @@
+ 	return pci_module_init(&k2_sata_pci_driver);
+ }
+ 
++
+ static void __exit k2_sata_exit(void)
+ {
+ 	pci_unregister_driver(&k2_sata_pci_driver);
+@@ -398,6 +470,7 @@
+ MODULE_DESCRIPTION("low-level driver for K2 SATA controller");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(pci, k2_sata_pci_tbl);
++MODULE_VERSION(DRV_VERSION);
+ 
+ module_init(k2_sata_init);
+ module_exit(k2_sata_exit);
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_sx4.c kernel-source-2.6.8-2.6.8/drivers/scsi/sata_sx4.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_sx4.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/sata_sx4.c	2006-08-11 14:32:25.358724617 -0600
+@@ -40,7 +40,7 @@
+ #include "sata_promise.h"
+ 
+ #define DRV_NAME	"sata_sx4"
+-#define DRV_VERSION	"0.50"
++#define DRV_VERSION	"0.7"
+ 
+ 
+ enum {
+@@ -146,8 +146,6 @@
+ 
+ 
+ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+-static void pdc20621_dma_setup(struct ata_queued_cmd *qc);
+-static void pdc20621_dma_start(struct ata_queued_cmd *qc);
+ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+ static void pdc_eng_timeout(struct ata_port *ap);
+ static void pdc_20621_phy_reset (struct ata_port *ap);
+@@ -157,8 +155,6 @@
+ static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+ static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+ static void pdc20621_host_stop(struct ata_host_set *host_set);
+-static inline void pdc_dma_complete (struct ata_port *ap,
+-                                     struct ata_queued_cmd *qc, int have_err);
+ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
+ static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
+ static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, 
+@@ -172,11 +168,13 @@
+ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, 
+ 				 void *psource, u32 offset, u32 size);
+ static void pdc20621_irq_clear(struct ata_port *ap);
++static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
+ 
+ 
+ static Scsi_Host_Template pdc_sata_sht = {
+ 	.module			= THIS_MODULE,
+ 	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
+ 	.queuecommand		= ata_scsi_queuecmd,
+ 	.eh_strategy_handler	= ata_scsi_error,
+ 	.can_queue		= ATA_DEF_QUEUE,
+@@ -195,14 +193,13 @@
+ static struct ata_port_operations pdc_20621_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.tf_load		= pdc_tf_load_mmio,
+-	.tf_read		= ata_tf_read_mmio,
+-	.check_status		= ata_check_status_mmio,
++	.tf_read		= ata_tf_read,
++	.check_status		= ata_check_status,
+ 	.exec_command		= pdc_exec_command_mmio,
++	.dev_select		= ata_std_dev_select,
+ 	.phy_reset		= pdc_20621_phy_reset,
+-	.bmdma_setup            = pdc20621_dma_setup,
+-	.bmdma_start            = pdc20621_dma_start,
+ 	.qc_prep		= pdc20621_qc_prep,
+-	.qc_issue		= ata_qc_issue_prot,
++	.qc_issue		= pdc20621_qc_issue_prot,
+ 	.eng_timeout		= pdc_eng_timeout,
+ 	.irq_handler		= pdc20621_interrupt,
+ 	.irq_clear		= pdc20621_irq_clear,
+@@ -217,7 +214,8 @@
+ 		.sht		= &pdc_sata_sht,
+ 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ 				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
+-		.pio_mask	= 0x03, /* pio3-4 */
++		.pio_mask	= 0x1f, /* pio0-4 */
++		.mwdma_mask	= 0x07, /* mwdma0-2 */
+ 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
+ 		.port_ops	= &pdc_20621_ops,
+ 	},
+@@ -250,7 +248,7 @@
+ 
+ static int pdc_port_start(struct ata_port *ap)
+ {
+-	struct pci_dev *pdev = ap->host_set->pdev;
++	struct device *dev = ap->host_set->dev;
+ 	struct pdc_port_priv *pp;
+ 	int rc;
+ 
+@@ -265,7 +263,7 @@
+ 	}
+ 	memset(pp, 0, sizeof(*pp));
+ 
+-	pp->pkt = pci_alloc_consistent(pdev, 128, &pp->pkt_dma);
++	pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
+ 	if (!pp->pkt) {
+ 		rc = -ENOMEM;
+ 		goto err_out_kfree;
+@@ -285,11 +283,11 @@
+ 
+ static void pdc_port_stop(struct ata_port *ap)
+ {
+-	struct pci_dev *pdev = ap->host_set->pdev;
++	struct device *dev = ap->host_set->dev;
+ 	struct pdc_port_priv *pp = ap->private_data;
+ 
+ 	ap->private_data = NULL;
+-	pci_free_consistent(pdev, 128, pp->pkt, pp->pkt_dma);
++	dma_free_coherent(dev, 128, pp->pkt, pp->pkt_dma);
+ 	kfree(pp);
+ 	ata_port_stop(ap);
+ }
+@@ -377,7 +375,10 @@
+ 
+ 	/* dimm dma S/G, and next-pkt */
+ 	dw = i >> 2;
+-	buf32[dw] = cpu_to_le32(dimm_sg);
++	if (tf->protocol == ATA_PROT_NODATA)
++		buf32[dw] = 0;
++	else
++		buf32[dw] = cpu_to_le32(dimm_sg);
+ 	buf32[dw + 1] = 0;
+ 	i += 8;
+ 
+@@ -437,7 +438,7 @@
+ 		buf32[dw + 3]);
+ }
+ 
+-static void pdc20621_qc_prep(struct ata_queued_cmd *qc)
++static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
+ {
+ 	struct scatterlist *sg = qc->sg;
+ 	struct ata_port *ap = qc->ap;
+@@ -449,8 +450,7 @@
+ 	unsigned int i, last, idx, total_len = 0, sgt_len;
+ 	u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
+ 
+-	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+-		return;
++	assert(qc->flags & ATA_QCFLAG_DMAMAP);
+ 
+ 	VPRINTK("ata%u: ENTER\n", ap->id);
+ 
+@@ -501,6 +501,56 @@
+ 	VPRINTK("ata pkt buf ofs %u, prd size %u, mmio copied\n", i, sgt_len);
+ }
+ 
++static void pdc20621_nodata_prep(struct ata_queued_cmd *qc)
++{
++	struct ata_port *ap = qc->ap;
++	struct pdc_port_priv *pp = ap->private_data;
++	void *mmio = ap->host_set->mmio_base;
++	struct pdc_host_priv *hpriv = ap->host_set->private_data;
++	void *dimm_mmio = hpriv->dimm_mmio;
++	unsigned int portno = ap->port_no;
++	unsigned int i;
++
++	VPRINTK("ata%u: ENTER\n", ap->id);
++
++	/* hard-code chip #0 */
++	mmio += PDC_CHIP0_OFS;
++
++	i = pdc20621_ata_pkt(&qc->tf, qc->dev->devno, &pp->dimm_buf[0], portno);
++
++	if (qc->tf.flags & ATA_TFLAG_LBA48)
++		i = pdc_prep_lba48(&qc->tf, &pp->dimm_buf[0], i);
++	else
++		i = pdc_prep_lba28(&qc->tf, &pp->dimm_buf[0], i);
++
++	pdc_pkt_footer(&qc->tf, &pp->dimm_buf[0], i);
++
++	/* copy three S/G tables and two packets to DIMM MMIO window */
++	memcpy_toio(dimm_mmio + (portno * PDC_DIMM_WINDOW_STEP),
++		    &pp->dimm_buf, PDC_DIMM_HEADER_SZ);
++
++	/* force host FIFO dump */
++	writel(0x00000001, mmio + PDC_20621_GENERAL_CTL);
++
++	readl(dimm_mmio);	/* MMIO PCI posting flush */
++
++	VPRINTK("ata pkt buf ofs %u, mmio copied\n", i);
++}
++
++static void pdc20621_qc_prep(struct ata_queued_cmd *qc)
++{
++	switch (qc->tf.protocol) {
++	case ATA_PROT_DMA:
++		pdc20621_dma_prep(qc);
++		break;
++	case ATA_PROT_NODATA:
++		pdc20621_nodata_prep(qc);
++		break;
++	default:
++		break;
++	}
++}
++
+ static void __pdc20621_push_hdma(struct ata_queued_cmd *qc,
+ 				 unsigned int seq,
+ 				 u32 pkt_ofs)
+@@ -576,13 +626,7 @@
+ static inline void pdc20621_dump_hdma(struct ata_queued_cmd *qc) { }
+ #endif /* ATA_VERBOSE_DEBUG */
+ 
+-static void pdc20621_dma_setup(struct ata_queued_cmd *qc)
+-{
+-	/* nothing for now.  later, we will call standard
+-	 * code in libata-core for ATAPI here */
+-}
+-
+-static void pdc20621_dma_start(struct ata_queued_cmd *qc)
++static void pdc20621_packet_start(struct ata_queued_cmd *qc)
+ {
+ 	struct ata_port *ap = qc->ap;
+ 	struct ata_host_set *host_set = ap->host_set;
+@@ -590,24 +634,21 @@
+ 	void *mmio = host_set->mmio_base;
+ 	unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
+ 	u8 seq = (u8) (port_no + 1);
+-	unsigned int doing_hdma = 0, port_ofs;
++	unsigned int port_ofs;
+ 
+ 	/* hard-code chip #0 */
+ 	mmio += PDC_CHIP0_OFS;
+ 
+ 	VPRINTK("ata%u: ENTER\n", ap->id);
+ 
++	wmb();			/* flush PRD, pkt writes */
++
+ 	port_ofs = PDC_20621_DIMM_BASE + (PDC_DIMM_WINDOW_STEP * port_no);
+ 
+ 	/* if writing, we (1) DMA to DIMM, then (2) do ATA command */
+-	if (rw) {
+-		doing_hdma = 1;
++	if (rw && qc->tf.protocol == ATA_PROT_DMA) {
+ 		seq += 4;
+-	}
+-
+-	wmb();			/* flush PRD, pkt writes */
+ 
+-	if (doing_hdma) {
+ 		pdc20621_dump_hdma(qc);
+ 		pdc20621_push_hdma(qc, seq, port_ofs + PDC_DIMM_HOST_PKT);
+ 		VPRINTK("queued ofs 0x%x (%u), seq %u\n",
+@@ -628,6 +669,25 @@
+ 	}
+ }
+ 
++static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc)
++{
++	switch (qc->tf.protocol) {
++	case ATA_PROT_DMA:
++	case ATA_PROT_NODATA:
++		pdc20621_packet_start(qc);
++		return 0;
++
++	case ATA_PROT_ATAPI_DMA:
++		BUG();
++		break;
++
++	default:
++		break;
++	}
++
++	return ata_qc_issue_prot(qc);
++}
++
+ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
+                                           struct ata_queued_cmd *qc,
+ 					  unsigned int doing_hdma,
+@@ -648,7 +708,8 @@
+ 		if (doing_hdma) {
+ 			VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
+ 				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
+-			pdc_dma_complete(ap, qc, 0);
++			/* get drive status; clear intr; complete txn */
++			ata_qc_complete(qc, ata_wait_idle(ap));
+ 			pdc20621_pop_hdma(qc);
+ 		}
+ 
+@@ -685,7 +746,8 @@
+ 		else {
+ 			VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
+ 				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
+-			pdc_dma_complete(ap, qc, 0);
++			/* get drive status; clear intr; complete txn */
++			ata_qc_complete(qc, ata_wait_idle(ap));
+ 			pdc20621_pop_hdma(qc);
+ 		}
+ 		handled = 1;
+@@ -779,16 +841,6 @@
+ 	return IRQ_RETVAL(handled);
+ }
+ 
+-static inline void pdc_dma_complete (struct ata_port *ap,
+-                                     struct ata_queued_cmd *qc,
+-				     int have_err)
+-{
+-	u8 err_bit = have_err ? ATA_ERR : 0;
+-
+-	/* get drive status; clear intr; complete txn */
+-	ata_qc_complete(qc, ata_wait_idle(ap) | err_bit);
+-}
+-
+ static void pdc_eng_timeout(struct ata_port *ap)
+ {
+ 	u8 drv_stat;
+@@ -813,17 +865,9 @@
+ 
+ 	switch (qc->tf.protocol) {
+ 	case ATA_PROT_DMA:
+-		printk(KERN_ERR "ata%u: DMA timeout\n", ap->id);
+-		ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
+-		break;
+-
+ 	case ATA_PROT_NODATA:
+-		drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+-
+-		printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x\n",
+-		       ap->id, qc->tf.command, drv_stat);
+-
+-		ata_qc_complete(qc, drv_stat);
++		printk(KERN_ERR "ata%u: command timeout\n", ap->id);
++		ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
+ 		break;
+ 
+ 	default:
+@@ -842,15 +886,17 @@
+ 
+ static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+-	if (tf->protocol != ATA_PROT_DMA)
+-		ata_tf_load_mmio(ap, tf);
++	WARN_ON (tf->protocol == ATA_PROT_DMA ||
++		 tf->protocol == ATA_PROT_NODATA);
++	ata_tf_load(ap, tf);
+ }
+ 
+ 
+ static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+-	if (tf->protocol != ATA_PROT_DMA)
+-		ata_exec_command_mmio(ap, tf);
++	WARN_ON (tf->protocol == ATA_PROT_DMA ||
++		 tf->protocol == ATA_PROT_NODATA);
++	ata_exec_command(ap, tf);
+ }
+ 
+ 
+@@ -1144,8 +1190,7 @@
+ 	   		error = 0;
+ 	   		break;     
+ 		}
+-		set_current_state(TASK_UNINTERRUPTIBLE);
+-		schedule_timeout((i * 100) * HZ / 1000 + 1);
++		msleep(i*100);
+    	}
+    	return error;
+ }
+@@ -1178,8 +1223,7 @@
+ 	readl(mmio + PDC_TIME_CONTROL);
+ 
+ 	/* Wait 3 seconds */
+-	set_current_state(TASK_UNINTERRUPTIBLE);
+-	schedule_timeout(3 * HZ);
++	msleep(3000);
+ 
+ 	/* 
+ 	   When timer is enabled, counter is decreased every internal
+@@ -1353,7 +1397,7 @@
+ 	}
+ 
+ 	memset(probe_ent, 0, sizeof(*probe_ent));
+-	probe_ent->pdev = pdev;
++	probe_ent->dev = pci_dev_to_dev(pdev);
+ 	INIT_LIST_HEAD(&probe_ent->node);
+ 
+ 	mmio_base = ioremap(pci_resource_start(pdev, 3),
+@@ -1384,6 +1428,7 @@
+ 	probe_ent->sht		= pdc_port_info[board_idx].sht;
+ 	probe_ent->host_flags	= pdc_port_info[board_idx].host_flags;
+ 	probe_ent->pio_mask	= pdc_port_info[board_idx].pio_mask;
++	probe_ent->mwdma_mask	= pdc_port_info[board_idx].mwdma_mask;
+ 	probe_ent->udma_mask	= pdc_port_info[board_idx].udma_mask;
+ 	probe_ent->port_ops	= pdc_port_info[board_idx].port_ops;
+ 
+@@ -1394,21 +1439,11 @@
+ 	probe_ent->private_data = hpriv;
+ 	base += PDC_CHIP0_OFS;
+ 
++	probe_ent->n_ports = 4;
+ 	pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
+ 	pdc_sata_setup_port(&probe_ent->port[1], base + 0x280);
+-
+-	/* notice 4-port boards */
+-	switch (board_idx) {
+-	case board_20621:
+-       		probe_ent->n_ports = 4;
+-
+-		pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
+-		pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
+-		break;
+-	default:
+-		BUG();
+-		break;
+-	}
++	pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
++	pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
+ 
+ 	pci_set_master(pdev);
+ 
+@@ -1457,6 +1492,7 @@
+ MODULE_DESCRIPTION("Promise SATA low-level driver");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(pci, pdc_sata_pci_tbl);
++MODULE_VERSION(DRV_VERSION);
+ 
+ module_init(pdc_sata_init);
+ module_exit(pdc_sata_exit);
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_uli.c kernel-source-2.6.8-2.6.8/drivers/scsi/sata_uli.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_uli.c	1969-12-31 17:00:00.000000000 -0700
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/sata_uli.c	2006-08-11 14:32:25.387050826 -0600
+@@ -0,0 +1,280 @@
++/*
++ *  sata_uli.c - ULi Electronics SATA
++ *
++ *  The contents of this file are subject to the Open
++ *  Software License version 1.1 that can be found at
++ *  http://www.opensource.org/licenses/osl-1.1.txt and is included herein
++ *  by reference.
++ *
++ *  Alternatively, the contents of this file may be used under the terms
++ *  of the GNU General Public License version 2 (the "GPL") as distributed
++ *  in the kernel source COPYING file, in which case the provisions of
++ *  the GPL are applicable instead of the above.  If you wish to allow
++ *  the use of your version of this file only under the terms of the
++ *  GPL and not to allow others to use your version of this file under
++ *  the OSL, indicate your decision by deleting the provisions above and
++ *  replace them with the notice and other provisions required by the GPL.
++ *  If you do not delete the provisions above, a recipient may use your
++ *  version of this file under either the OSL or the GPL.
++ *
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/blkdev.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include "scsi.h"
++#include <scsi/scsi_host.h>
++#include <linux/libata.h>
++
++#define DRV_NAME	"sata_uli"
++#define DRV_VERSION	"0.5"
++
++enum {
++	uli_5289		= 0,
++	uli_5287		= 1,
++	uli_5281		= 2,
++
++	/* PCI configuration registers */
++	ULI5287_BASE		= 0x90, /* sata0 phy SCR registers */
++	ULI5287_OFFS		= 0x10, /* offset from sata0->sata1 phy regs */
++	ULI5281_BASE		= 0x60, /* sata0 phy SCR  registers */
++	ULI5281_OFFS		= 0x60, /* offset from sata0->sata1 phy regs */
++};
++
++static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
++static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg);
++static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
++
++static struct pci_device_id uli_pci_tbl[] = {
++	{ PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 },
++	{ PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 },
++	{ PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 },
++	{ }	/* terminate list */
++};
++
++
++static struct pci_driver uli_pci_driver = {
++	.name			= DRV_NAME,
++	.id_table		= uli_pci_tbl,
++	.probe			= uli_init_one,
++	.remove			= ata_pci_remove_one,
++};
++
++static Scsi_Host_Template uli_sht = {
++	.module			= THIS_MODULE,
++	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
++	.queuecommand		= ata_scsi_queuecmd,
++	.eh_strategy_handler	= ata_scsi_error,
++	.can_queue		= ATA_DEF_QUEUE,
++	.this_id		= ATA_SHT_THIS_ID,
++	.sg_tablesize		= LIBATA_MAX_PRD,
++	.max_sectors		= ATA_MAX_SECTORS,
++	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
++	.emulated		= ATA_SHT_EMULATED,
++	.use_clustering		= ATA_SHT_USE_CLUSTERING,
++	.proc_name		= DRV_NAME,
++	.dma_boundary		= ATA_DMA_BOUNDARY,
++	.slave_configure	= ata_scsi_slave_config,
++	.bios_param		= ata_std_bios_param,
++};
++
++static struct ata_port_operations uli_ops = {
++	.port_disable		= ata_port_disable,
++
++	.tf_load		= ata_tf_load,
++	.tf_read		= ata_tf_read,
++	.check_status		= ata_check_status,
++	.exec_command		= ata_exec_command,
++	.dev_select		= ata_std_dev_select,
++
++	.phy_reset		= sata_phy_reset,
++
++	.bmdma_setup            = ata_bmdma_setup,
++	.bmdma_start            = ata_bmdma_start,
++	.qc_prep		= ata_qc_prep,
++	.qc_issue		= ata_qc_issue_prot,
++
++	.eng_timeout		= ata_eng_timeout,
++
++	.irq_handler		= ata_interrupt,
++	.irq_clear		= ata_bmdma_irq_clear,
++
++	.scr_read		= uli_scr_read,
++	.scr_write		= uli_scr_write,
++
++	.port_start		= ata_port_start,
++	.port_stop		= ata_port_stop,
++};
++
++static struct ata_port_info uli_port_info = {
++	.sht            = &uli_sht,
++	.host_flags     = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
++			  ATA_FLAG_NO_LEGACY,
++	.pio_mask       = 0x03,		//support pio mode 4 (FIXME)
++	.udma_mask      = 0x7f,		//support udma mode 6
++	.port_ops       = &uli_ops,
++};
++
++
++MODULE_AUTHOR("Peer Chen");
++MODULE_DESCRIPTION("low-level driver for ULi Electronics SATA controller");
++MODULE_LICENSE("GPL");
++MODULE_DEVICE_TABLE(pci, uli_pci_tbl);
++MODULE_VERSION(DRV_VERSION);
++
++static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
++{
++	return ap->ioaddr.scr_addr + (4 * sc_reg);
++}
++
++static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
++{
++	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
++	unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
++	u32 val;
++
++	pci_read_config_dword(pdev, cfg_addr, &val);
++	return val;
++}
++
++static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
++{
++	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
++	unsigned int cfg_addr = get_scr_cfg_addr(ap, scr);
++
++	pci_write_config_dword(pdev, cfg_addr, val);
++}
++
++static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg)
++{
++	if (sc_reg > SCR_CONTROL)
++		return 0xffffffffU;
++
++	return uli_scr_cfg_read(ap, sc_reg);
++}
++
++static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
++{
++	if (sc_reg > SCR_CONTROL)	//SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0
++		return;
++
++	uli_scr_cfg_write(ap, sc_reg, val);
++}
++
++/* move to PCI layer, integrate w/ MSI stuff */
++static void pci_enable_intx(struct pci_dev *pdev)
++{
++	u16 pci_command;
++
++	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
++	if (pci_command & PCI_COMMAND_INTX_DISABLE) {
++		pci_command &= ~PCI_COMMAND_INTX_DISABLE;
++		pci_write_config_word(pdev, PCI_COMMAND, pci_command);
++	}
++}
++
++static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
++{
++	struct ata_probe_ent *probe_ent;
++	struct ata_port_info *ppi;
++	int rc;
++	unsigned int board_idx = (unsigned int) ent->driver_data;
++
++	rc = pci_enable_device(pdev);
++	if (rc)
++		return rc;
++
++	rc = pci_request_regions(pdev, DRV_NAME);
++	if (rc)
++		goto err_out;
++
++	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
++	if (rc)
++		goto err_out_regions;
++	rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
++	if (rc)
++		goto err_out_regions;
++
++	ppi = &uli_port_info;
++	probe_ent = ata_pci_init_native_mode(pdev, &ppi);
++	if (!probe_ent) {
++		rc = -ENOMEM;
++		goto err_out_regions;
++	}
++	
++	switch (board_idx) {
++	case uli_5287:
++		probe_ent->port[0].scr_addr = ULI5287_BASE;
++		probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
++       		probe_ent->n_ports = 4;
++
++       		probe_ent->port[2].cmd_addr = pci_resource_start(pdev, 0) + 8;
++		probe_ent->port[2].altstatus_addr =
++		probe_ent->port[2].ctl_addr =
++			(pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4;
++		probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16;
++		probe_ent->port[2].scr_addr = ULI5287_BASE + ULI5287_OFFS*4;
++
++		probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8;
++		probe_ent->port[3].altstatus_addr =
++		probe_ent->port[3].ctl_addr =
++			(pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4;
++		probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24;
++		probe_ent->port[3].scr_addr = ULI5287_BASE + ULI5287_OFFS*5;
++
++		ata_std_ports(&probe_ent->port[2]);
++		ata_std_ports(&probe_ent->port[3]);
++		break;
++
++	case uli_5289:
++		probe_ent->port[0].scr_addr = ULI5287_BASE;
++		probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
++		break;
++
++	case uli_5281:
++		probe_ent->port[0].scr_addr = ULI5281_BASE;
++		probe_ent->port[1].scr_addr = ULI5281_BASE + ULI5281_OFFS;
++		break;
++
++	default:
++		BUG();
++		break;
++	}
++
++	pci_set_master(pdev);
++	pci_enable_intx(pdev);
++
++	/* FIXME: check ata_device_add return value */
++	ata_device_add(probe_ent);
++	kfree(probe_ent);
++
++	return 0;
++
++err_out_regions:
++	pci_release_regions(pdev);
++
++err_out:
++	pci_disable_device(pdev);
++	return rc;
++
++}
++
++static int __init uli_init(void)
++{
++	return pci_module_init(&uli_pci_driver);
++}
++
++static void __exit uli_exit(void)
++{
++	pci_unregister_driver(&uli_pci_driver);
++}
++
++
++module_init(uli_init);
++module_exit(uli_exit);
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_via.c kernel-source-2.6.8-2.6.8/drivers/scsi/sata_via.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_via.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/sata_via.c	2006-08-11 14:32:25.359701383 -0600
+@@ -38,7 +38,7 @@
+ #include <asm/io.h>
+ 
+ #define DRV_NAME	"sata_via"
+-#define DRV_VERSION	"0.20"
++#define DRV_VERSION	"1.0"
+ 
+ enum {
+ 	via_sata		= 0,
+@@ -81,6 +81,7 @@
+ static Scsi_Host_Template svia_sht = {
+ 	.module			= THIS_MODULE,
+ 	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
+ 	.queuecommand		= ata_scsi_queuecmd,
+ 	.eh_strategy_handler	= ata_scsi_error,
+ 	.can_queue		= ATA_DEF_QUEUE,
+@@ -99,15 +100,16 @@
+ static struct ata_port_operations svia_sata_ops = {
+ 	.port_disable		= ata_port_disable,
+ 
+-	.tf_load		= ata_tf_load_pio,
+-	.tf_read		= ata_tf_read_pio,
+-	.check_status		= ata_check_status_pio,
+-	.exec_command		= ata_exec_command_pio,
++	.tf_load		= ata_tf_load,
++	.tf_read		= ata_tf_read,
++	.check_status		= ata_check_status,
++	.exec_command		= ata_exec_command,
++	.dev_select		= ata_std_dev_select,
+ 
+ 	.phy_reset		= sata_phy_reset,
+ 
+-	.bmdma_setup            = ata_bmdma_setup_pio,
+-	.bmdma_start            = ata_bmdma_start_pio,
++	.bmdma_setup            = ata_bmdma_setup,
++	.bmdma_start            = ata_bmdma_start,
+ 	.qc_prep		= ata_qc_prep,
+ 	.qc_issue		= ata_qc_issue_prot,
+ 
+@@ -123,10 +125,20 @@
+ 	.port_stop		= ata_port_stop,
+ };
+ 
++static struct ata_port_info svia_port_info = {
++	.sht		= &svia_sht,
++	.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST | ATA_FLAG_NO_LEGACY,
++	.pio_mask	= 0x1f,
++	.mwdma_mask	= 0x07,
++	.udma_mask	= 0x7f,
++	.port_ops	= &svia_sata_ops,
++};
++
+ MODULE_AUTHOR("Jeff Garzik");
+ MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(pci, svia_pci_tbl);
++MODULE_VERSION(DRV_VERSION);
+ 
+ static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg)
+ {
+@@ -156,6 +168,7 @@
+ 	static int printed_version;
+ 	unsigned int i;
+ 	int rc;
++	struct ata_port_info *ppi;
+ 	struct ata_probe_ent *probe_ent;
+ 	u8 tmp8;
+ 
+@@ -196,41 +209,17 @@
+ 	if (rc)
+ 		goto err_out_regions;
+ 
+-	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
++	ppi = &svia_port_info;
++	probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+ 	if (!probe_ent) {
+ 		printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
+ 		       pci_name(pdev));
+ 		rc = -ENOMEM;
+ 		goto err_out_regions;
+ 	}
+-	memset(probe_ent, 0, sizeof(*probe_ent));
+-	INIT_LIST_HEAD(&probe_ent->node);
+-	probe_ent->pdev = pdev;
+-	probe_ent->sht = &svia_sht;
+-	probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
+-				ATA_FLAG_NO_LEGACY;
+-	probe_ent->port_ops = &svia_sata_ops;
+-	probe_ent->n_ports = 2;
+-	probe_ent->irq = pdev->irq;
+-	probe_ent->irq_flags = SA_SHIRQ;
+-	probe_ent->pio_mask = 0x1f;
+-	probe_ent->udma_mask = 0x7f;
+-
+-	probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
+-	ata_std_ports(&probe_ent->port[0]);
+-	probe_ent->port[0].altstatus_addr =
+-	probe_ent->port[0].ctl_addr =
+-		pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
+-	probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
++
+ 	probe_ent->port[0].scr_addr =
+ 		svia_scr_addr(pci_resource_start(pdev, 5), 0);
+-
+-	probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
+-	ata_std_ports(&probe_ent->port[1]);
+-	probe_ent->port[1].altstatus_addr =
+-	probe_ent->port[1].ctl_addr =
+-		pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
+-	probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
+ 	probe_ent->port[1].scr_addr =
+ 		svia_scr_addr(pci_resource_start(pdev, 5), 1);
+ 
+diff -urN kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_vsc.c kernel-source-2.6.8-2.6.8/drivers/scsi/sata_vsc.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/sata_vsc.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/sata_vsc.c	2006-08-11 14:32:25.360678149 -0600
+@@ -26,7 +26,7 @@
+ #include <linux/libata.h>
+ 
+ #define DRV_NAME	"sata_vsc"
+-#define DRV_VERSION	"0.01"
++#define DRV_VERSION	"1.0"
+ 
+ /* Interrupt register offsets (from chip base address) */
+ #define VSC_SATA_INT_STAT_OFFSET	0x00
+@@ -190,6 +190,7 @@
+ static Scsi_Host_Template vsc_sata_sht = {
+ 	.module			= THIS_MODULE,
+ 	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
+ 	.queuecommand		= ata_scsi_queuecmd,
+ 	.eh_strategy_handler	= ata_scsi_error,
+ 	.can_queue		= ATA_DEF_QUEUE,
+@@ -210,11 +211,12 @@
+ 	.port_disable		= ata_port_disable,
+ 	.tf_load		= vsc_sata_tf_load,
+ 	.tf_read		= vsc_sata_tf_read,
+-	.exec_command		= ata_exec_command_mmio,
+-	.check_status		= ata_check_status_mmio,
++	.exec_command		= ata_exec_command,
++	.check_status		= ata_check_status,
++	.dev_select		= ata_std_dev_select,
+ 	.phy_reset		= sata_phy_reset,
+-	.bmdma_setup            = ata_bmdma_setup_mmio,
+-	.bmdma_start            = ata_bmdma_start_mmio,
++	.bmdma_setup            = ata_bmdma_setup,
++	.bmdma_start            = ata_bmdma_start,
+ 	.qc_prep		= ata_qc_prep,
+ 	.qc_issue		= ata_qc_issue_prot,
+ 	.eng_timeout		= ata_eng_timeout,
+@@ -291,7 +293,7 @@
+ 		goto err_out_regions;
+ 	}
+ 	memset(probe_ent, 0, sizeof(*probe_ent));
+-	probe_ent->pdev = pdev;
++	probe_ent->dev = pci_dev_to_dev(pdev);
+ 	INIT_LIST_HEAD(&probe_ent->node);
+ 
+ 	mmio_base = ioremap(pci_resource_start(pdev, 0),
+@@ -320,6 +322,7 @@
+ 	 * if we don't fill these
+ 	 */
+ 	probe_ent->pio_mask = 0x1f;
++	probe_ent->mwdma_mask = 0x07;
+ 	probe_ent->udma_mask = 0x7f;
+ 
+ 	/* We have 4 ports per PCI function */
+@@ -330,6 +333,14 @@
+ 
+ 	pci_set_master(pdev);
+ 
++	/* 
++	 * Config offset 0x98 is "Extended Control and Status Register 0"
++	 * Default value is (1 << 28).  All bits except bit 28 are reserved in
++	 * DPA mode.  If bit 28 is set, LED 0 reflects all ports' activity.
++	 * If bit 28 is clear, each port has its own LED.
++	 */
++	pci_write_config_dword(pdev, 0x98, 0);
++
+ 	/* FIXME: check ata_device_add return value */
+ 	ata_device_add(probe_ent);
+ 	kfree(probe_ent);
+@@ -382,6 +393,7 @@
+ MODULE_DESCRIPTION("low-level driver for Vitesse VSC7174 SATA controller");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(pci, vsc_sata_pci_tbl);
++MODULE_VERSION(DRV_VERSION);
+ 
+ module_init(vsc_sata_init);
+ module_exit(vsc_sata_exit);
+diff -urN kernel-source-2.6.8-2.6.8.orig/include/linux/ata.h kernel-source-2.6.8-2.6.8/include/linux/ata.h
+--- kernel-source-2.6.8-2.6.8.orig/include/linux/ata.h	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/include/linux/ata.h	2006-08-11 14:32:25.315746921 -0600
+@@ -24,6 +24,8 @@
+ #ifndef __LINUX_ATA_H__
+ #define __LINUX_ATA_H__
+ 
++#include <linux/types.h>
++
+ /* defines only for the constants which don't work well as enums */
+ #define ATA_DMA_BOUNDARY	0xffffUL
+ #define ATA_DMA_MASK		0xffffffffULL
+@@ -33,8 +35,6 @@
+ 	ATA_MAX_DEVICES		= 2,	/* per bus/port */
+ 	ATA_MAX_PRD		= 256,	/* we could make these 256/256 */
+ 	ATA_SECT_SIZE		= 512,
+-	ATA_SECT_SIZE_MASK	= (ATA_SECT_SIZE - 1),
+-	ATA_SECT_DWORDS		= ATA_SECT_SIZE / sizeof(u32),
+ 
+ 	ATA_ID_WORDS		= 256,
+ 	ATA_ID_PROD_OFS		= 27,
+@@ -42,6 +42,7 @@
+ 	ATA_ID_SERNO_OFS	= 10,
+ 	ATA_ID_MAJOR_VER	= 80,
+ 	ATA_ID_PIO_MODES	= 64,
++	ATA_ID_MWDMA_MODES	= 63,
+ 	ATA_ID_UDMA_MODES	= 88,
+ 	ATA_ID_PIO4		= (1 << 1),
+ 
+@@ -133,13 +134,24 @@
+ 	XFER_UDMA_2		= 0x42,
+ 	XFER_UDMA_1		= 0x41,
+ 	XFER_UDMA_0		= 0x40,
++	XFER_MW_DMA_2		= 0x22,
++	XFER_MW_DMA_1		= 0x21,
++	XFER_MW_DMA_0		= 0x20,
+ 	XFER_PIO_4		= 0x0C,
+ 	XFER_PIO_3		= 0x0B,
++	XFER_PIO_2		= 0x0A,
++	XFER_PIO_1		= 0x09,
++	XFER_PIO_0		= 0x08,
++	XFER_SW_DMA_2		= 0x12,
++	XFER_SW_DMA_1		= 0x11,
++	XFER_SW_DMA_0		= 0x10,
++	XFER_PIO_SLOW		= 0x00,
+ 
+ 	/* ATAPI stuff */
+ 	ATAPI_PKT_DMA		= (1 << 0),
+ 	ATAPI_DMADIR		= (1 << 2),	/* ATAPI data dir:
+ 						   0=to device, 1=to host */
++	ATAPI_CDB_LEN		= 16,
+ 
+ 	/* cable types */
+ 	ATA_CBL_NONE		= 0,
+@@ -169,16 +181,22 @@
+ 	ATA_PROT_PIO,		/* PIO single sector */
+ 	ATA_PROT_PIO_MULT,	/* PIO multiple sector */
+ 	ATA_PROT_DMA,		/* DMA */
+-	ATA_PROT_ATAPI,		/* packet command */
++	ATA_PROT_ATAPI,		/* packet command, PIO data xfer*/
++	ATA_PROT_ATAPI_NODATA,	/* packet command, no data */
+ 	ATA_PROT_ATAPI_DMA,	/* packet command with special DMA sauce */
+ };
+ 
++enum ata_ioctls {
++	ATA_IOC_GET_IO32	= 0x309,
++	ATA_IOC_SET_IO32	= 0x324,
++};
++
+ /* core structures */
+ 
+ struct ata_prd {
+ 	u32			addr;
+ 	u32			flags_len;
+-} __attribute__((packed));
++};
+ 
+ struct ata_taskfile {
+ 	unsigned long		flags;		/* ATA_TFLAG_xxx */
+@@ -203,26 +221,39 @@
+ 	u8			command;	/* IO operation */
+ };
+ 
+-#define ata_id_is_ata(dev)	(((dev)->id[0] & (1 << 15)) == 0)
+-#define ata_id_rahead_enabled(dev) ((dev)->id[85] & (1 << 6))
+-#define ata_id_wcache_enabled(dev) ((dev)->id[85] & (1 << 5))
+-#define ata_id_has_lba48(dev)	((dev)->id[83] & (1 << 10))
+-#define ata_id_has_wcache(dev)	((dev)->id[82] & (1 << 5))
+-#define ata_id_has_pm(dev)	((dev)->id[82] & (1 << 3))
+-#define ata_id_has_lba(dev)	((dev)->id[49] & (1 << 9))
+-#define ata_id_has_dma(dev)	((dev)->id[49] & (1 << 8))
+-#define ata_id_removeable(dev)	((dev)->id[0] & (1 << 7))
+-#define ata_id_u32(dev,n)	\
+-	(((u32) (dev)->id[(n) + 1] << 16) | ((u32) (dev)->id[(n)]))
+-#define ata_id_u64(dev,n)	\
+-	( ((u64) dev->id[(n) + 3] << 48) |	\
+-	  ((u64) dev->id[(n) + 2] << 32) |	\
+-	  ((u64) dev->id[(n) + 1] << 16) |	\
+-	  ((u64) dev->id[(n) + 0]) )
++#define ata_id_is_ata(id)	(((id)[0] & (1 << 15)) == 0)
++#define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
++#define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
++#define ata_id_has_flush(id) ((id)[83] & (1 << 12))
++#define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13))
++#define ata_id_has_lba48(id)	((id)[83] & (1 << 10))
++#define ata_id_has_wcache(id)	((id)[82] & (1 << 5))
++#define ata_id_has_pm(id)	((id)[82] & (1 << 3))
++#define ata_id_has_lba(id)	((id)[49] & (1 << 9))
++#define ata_id_has_dma(id)	((id)[49] & (1 << 8))
++#define ata_id_removeable(id)	((id)[0] & (1 << 7))
++#define ata_id_u32(id,n)	\
++	(((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)]))
++#define ata_id_u64(id,n)	\
++	( ((u64) (id)[(n) + 3] << 48) |	\
++	  ((u64) (id)[(n) + 2] << 32) |	\
++	  ((u64) (id)[(n) + 1] << 16) |	\
++	  ((u64) (id)[(n) + 0]) )
++
++static inline int atapi_cdb_len(u16 *dev_id)
++{
++	u16 tmp = dev_id[0] & 0x3;
++	switch (tmp) {
++	case 0:		return 12;
++	case 1:		return 16;
++	default:	return -1;
++	}
++}
+ 
+ static inline int is_atapi_taskfile(struct ata_taskfile *tf)
+ {
+ 	return (tf->protocol == ATA_PROT_ATAPI) ||
++	       (tf->protocol == ATA_PROT_ATAPI_NODATA) ||
+ 	       (tf->protocol == ATA_PROT_ATAPI_DMA);
+ }
+ 
+diff -urN kernel-source-2.6.8-2.6.8.orig/include/linux/hdreg.h kernel-source-2.6.8-2.6.8/include/linux/hdreg.h
+--- kernel-source-2.6.8-2.6.8.orig/include/linux/hdreg.h	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/include/linux/hdreg.h	2006-08-11 14:32:25.492541535 -0600
+@@ -1,6 +1,9 @@
+ #ifndef _LINUX_HDREG_H
+ #define _LINUX_HDREG_H
+ 
++#ifdef __KERNEL__
++#include <linux/ata.h>
++
+ /*
+  * This file contains some defines for the AT-hd-controller.
+  * Various sources.
+@@ -55,7 +58,7 @@
+ #define IO			0x02
+ #define REL			0x04
+ #define TAG_MASK		0xf8
+-
++#endif /* __KERNEL__ */
+ 
+ /*
+  * Command Header sizes for IOCTL commands
+@@ -328,27 +331,6 @@
+ /* WIN_SETFEATURES sub-commands */
+ #define SETFEATURES_EN_8BIT	0x01	/* Enable 8-Bit Transfers */
+ #define SETFEATURES_EN_WCACHE	0x02	/* Enable write cache */
+-#define SETFEATURES_XFER	0x03	/* Set transfer mode */
+-#	define XFER_UDMA_7	0x47	/* 0100|0111 */
+-#	define XFER_UDMA_6	0x46	/* 0100|0110 */
+-#	define XFER_UDMA_5	0x45	/* 0100|0101 */
+-#	define XFER_UDMA_4	0x44	/* 0100|0100 */
+-#	define XFER_UDMA_3	0x43	/* 0100|0011 */
+-#	define XFER_UDMA_2	0x42	/* 0100|0010 */
+-#	define XFER_UDMA_1	0x41	/* 0100|0001 */
+-#	define XFER_UDMA_0	0x40	/* 0100|0000 */
+-#	define XFER_MW_DMA_2	0x22	/* 0010|0010 */
+-#	define XFER_MW_DMA_1	0x21	/* 0010|0001 */
+-#	define XFER_MW_DMA_0	0x20	/* 0010|0000 */
+-#	define XFER_SW_DMA_2	0x12	/* 0001|0010 */
+-#	define XFER_SW_DMA_1	0x11	/* 0001|0001 */
+-#	define XFER_SW_DMA_0	0x10	/* 0001|0000 */
+-#	define XFER_PIO_4	0x0C	/* 0000|1100 */
+-#	define XFER_PIO_3	0x0B	/* 0000|1011 */
+-#	define XFER_PIO_2	0x0A	/* 0000|1010 */
+-#	define XFER_PIO_1	0x09	/* 0000|1001 */
+-#	define XFER_PIO_0	0x08	/* 0000|1000 */
+-#	define XFER_PIO_SLOW	0x00	/* 0000|0000 */
+ #define SETFEATURES_DIS_DEFECT	0x04	/* Disable Defect Management */
+ #define SETFEATURES_EN_APM	0x05	/* Enable advanced power management */
+ #define SETFEATURES_EN_SAME_R	0x22	/* for a region ATA-1 */
+diff -urN kernel-source-2.6.8-2.6.8.orig/include/linux/libata.h kernel-source-2.6.8-2.6.8/include/linux/libata.h
+--- kernel-source-2.6.8-2.6.8.orig/include/linux/libata.h	2006-08-11 14:32:56.765652937 -0600
++++ kernel-source-2.6.8-2.6.8/include/linux/libata.h	2006-08-11 14:32:25.405609377 -0600
+@@ -25,6 +25,7 @@
+ 
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
++#include <linux/pci.h>
+ #include <asm/io.h>
+ #include <linux/ata.h>
+ #include <linux/workqueue.h>
+@@ -32,7 +33,6 @@
+ /*
+  * compile-time options
+  */
+-#undef ATA_FORCE_PIO		/* do not configure or use DMA */
+ #undef ATA_DEBUG		/* debugging output */
+ #undef ATA_VERBOSE_DEBUG	/* yet more debugging output */
+ #undef ATA_IRQ_TRAP		/* define to ack screaming irqs */
+@@ -69,6 +69,12 @@
+ /* defines only for the constants which don't work well as enums */
+ #define ATA_TAG_POISON		0xfafbfcfdU
+ 
++/* move to PCI layer? */
++static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
++{
++	return &pdev->dev;
++}
++
+ enum {
+ 	/* various global constants */
+ 	LIBATA_MAX_PRD		= ATA_MAX_PRD / 2,
+@@ -88,10 +94,7 @@
+ 	/* struct ata_device stuff */
+ 	ATA_DFLAG_LBA48		= (1 << 0), /* device supports LBA48 */
+ 	ATA_DFLAG_PIO		= (1 << 1), /* device currently in PIO mode */
+-	ATA_DFLAG_MASTER	= (1 << 2), /* is device 0? */
+-	ATA_DFLAG_WCACHE	= (1 << 3), /* has write cache we can
+-					     * (hopefully) flush? */
+-	ATA_DFLAG_LOCK_SECTORS	= (1 << 4), /* don't adjust max_sectors */
++	ATA_DFLAG_LOCK_SECTORS	= (1 << 2), /* don't adjust max_sectors */
+ 
+ 	ATA_DEV_UNKNOWN		= 0,	/* unknown device */
+ 	ATA_DEV_ATA		= 1,	/* ATA device */
+@@ -109,9 +112,9 @@
+ 	ATA_FLAG_SRST		= (1 << 5), /* use ATA SRST, not E.D.D. */
+ 	ATA_FLAG_MMIO		= (1 << 6), /* use MMIO, not PIO */
+ 	ATA_FLAG_SATA_RESET	= (1 << 7), /* use COMRESET */
++	ATA_FLAG_PIO_DMA	= (1 << 8), /* PIO cmds via DMA */
+ 
+ 	ATA_QCFLAG_ACTIVE	= (1 << 1), /* cmd not yet ack'd to scsi lyer */
+-	ATA_QCFLAG_DMA		= (1 << 2), /* data delivered via DMA */
+ 	ATA_QCFLAG_SG		= (1 << 3), /* have s/g table? */
+ 	ATA_QCFLAG_SINGLE	= (1 << 4), /* no s/g, just a single buffer */
+ 	ATA_QCFLAG_DMAMAP	= ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
+@@ -140,6 +143,13 @@
+ 	PORT_UNKNOWN		= 0,
+ 	PORT_ENABLED		= 1,
+ 	PORT_DISABLED		= 2,
++
++	/* encoding various smaller bitmaps into a single
++	 * unsigned long bitmap
++	 */
++	ATA_SHIFT_UDMA		= 0,
++	ATA_SHIFT_MWDMA		= 8,
++	ATA_SHIFT_PIO		= 11,
+ };
+ 
+ enum pio_task_states {
+@@ -182,13 +192,14 @@
+ 
+ struct ata_probe_ent {
+ 	struct list_head	node;
+-	struct pci_dev		*pdev;
++	struct device 		*dev;
+ 	struct ata_port_operations	*port_ops;
+ 	Scsi_Host_Template	*sht;
+ 	struct ata_ioports	port[ATA_MAX_PORTS];
+ 	unsigned int		n_ports;
+ 	unsigned int		hard_port_no;
+ 	unsigned int		pio_mask;
++	unsigned int		mwdma_mask;
+ 	unsigned int		udma_mask;
+ 	unsigned int		legacy_mode;
+ 	unsigned long		irq;
+@@ -200,7 +211,7 @@
+ 
+ struct ata_host_set {
+ 	spinlock_t		lock;
+-	struct pci_dev		*pdev;
++	struct device 		*dev;
+ 	unsigned long		irq;
+ 	void			*mmio_base;
+ 	unsigned int		n_ports;
+@@ -216,18 +227,24 @@
+ 	struct scsi_cmnd	*scsicmd;
+ 	void			(*scsidone)(struct scsi_cmnd *);
+ 
++	struct ata_taskfile	tf;
++	u8			cdb[ATAPI_CDB_LEN];
++
+ 	unsigned long		flags;		/* ATA_QCFLAG_xxx */
+ 	unsigned int		tag;
+ 	unsigned int		n_elem;
+ 
+-	int			pci_dma_dir;
++	int			dma_dir;
+ 
+ 	unsigned int		nsect;
+ 	unsigned int		cursect;
++
++	unsigned int		nbytes;
++	unsigned int		curbytes;
++
+ 	unsigned int		cursg;
+ 	unsigned int		cursg_ofs;
+ 
+-	struct ata_taskfile	tf;
+ 	struct scatterlist	sgent;
+ 	void			*buf_virt;
+ 
+@@ -252,8 +269,10 @@
+ 	unsigned int		class;		/* ATA_DEV_xxx */
+ 	unsigned int		devno;		/* 0 or 1 */
+ 	u16			id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
+-	unsigned int		pio_mode;
+-	unsigned int		udma_mode;
++	u8			pio_mode;
++	u8			dma_mode;
++	u8			xfer_mode;
++	unsigned int		xfer_shift;	/* ATA_SHIFT_xxx */
+ 
+ 	/* cache info about current transfer mode */
+ 	u8			xfer_protocol;	/* taskfile xfer protocol */
+@@ -279,8 +298,10 @@
+ 	unsigned int		bus_state;
+ 	unsigned int		port_state;
+ 	unsigned int		pio_mask;
++	unsigned int		mwdma_mask;
+ 	unsigned int		udma_mask;
+ 	unsigned int		cbl;	/* cable type; ATA_CBL_xxx */
++	unsigned int		cdb_len;
+ 
+ 	struct ata_device	device[ATA_MAX_DEVICES];
+ 
+@@ -305,16 +326,15 @@
+ 
+ 	void (*dev_config) (struct ata_port *, struct ata_device *);
+ 
+-	void (*set_piomode) (struct ata_port *, struct ata_device *,
+-			     unsigned int);
+-	void (*set_udmamode) (struct ata_port *, struct ata_device *,
+-			     unsigned int);
++	void (*set_piomode) (struct ata_port *, struct ata_device *);
++	void (*set_dmamode) (struct ata_port *, struct ata_device *);
+ 
+ 	void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
+ 	void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
+ 
+ 	void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
+ 	u8   (*check_status)(struct ata_port *ap);
++	void (*dev_select)(struct ata_port *ap, unsigned int device);
+ 
+ 	void (*phy_reset) (struct ata_port *ap);
+ 	void (*post_set_mode) (struct ata_port *ap);
+@@ -344,27 +364,26 @@
+ 	Scsi_Host_Template	*sht;
+ 	unsigned long		host_flags;
+ 	unsigned long		pio_mask;
++	unsigned long		mwdma_mask;
+ 	unsigned long		udma_mask;
+ 	struct ata_port_operations	*port_ops;
+ };
+ 
+-struct pci_bits {
+-	unsigned int		reg;	/* PCI config register to read */
+-	unsigned int		width;	/* 1 (8 bit), 2 (16 bit), 4 (32 bit) */
+-	unsigned long		mask;
+-	unsigned long		val;
+-};
+ 
+ extern void ata_port_probe(struct ata_port *);
++extern void __sata_phy_reset(struct ata_port *ap);
+ extern void sata_phy_reset(struct ata_port *ap);
+ extern void ata_bus_reset(struct ata_port *ap);
+ extern void ata_port_disable(struct ata_port *);
+ extern void ata_std_ports(struct ata_ioports *ioaddr);
++#ifdef CONFIG_PCI
+ extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
+ 			     unsigned int n_ports);
+ extern void ata_pci_remove_one (struct pci_dev *pdev);
++#endif /* CONFIG_PCI */
+ extern int ata_device_add(struct ata_probe_ent *ent);
+ extern int ata_scsi_detect(Scsi_Host_Template *sht);
++extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
+ extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
+ extern int ata_scsi_error(struct Scsi_Host *host);
+ extern int ata_scsi_release(struct Scsi_Host *host);
+@@ -372,16 +391,14 @@
+ /*
+  * Default driver ops implementations
+  */
+-extern void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf);
+-extern void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+-extern void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf);
+-extern void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf);
++extern void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf);
++extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
+ extern void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp);
+ extern void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf);
+-extern u8 ata_check_status_pio(struct ata_port *ap);
+-extern u8 ata_check_status_mmio(struct ata_port *ap);
+-extern void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf);
+-extern void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
++extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device);
++extern void ata_std_dev_select (struct ata_port *ap, unsigned int device);
++extern u8 ata_check_status(struct ata_port *ap);
++extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf);
+ extern int ata_port_start (struct ata_port *ap);
+ extern void ata_port_stop (struct ata_port *ap);
+ extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+@@ -391,22 +408,39 @@
+ 		unsigned int buflen);
+ extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
+ 		 unsigned int n_elem);
+-extern void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
++extern unsigned int ata_dev_classify(struct ata_taskfile *tf);
++extern void ata_dev_id_string(u16 *id, unsigned char *s,
+ 			      unsigned int ofs, unsigned int len);
+-extern void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc);
+-extern void ata_bmdma_start_mmio (struct ata_queued_cmd *qc);
+-extern void ata_bmdma_setup_pio (struct ata_queued_cmd *qc);
+-extern void ata_bmdma_start_pio (struct ata_queued_cmd *qc);
++extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
++extern void ata_bmdma_start (struct ata_queued_cmd *qc);
+ extern void ata_bmdma_irq_clear(struct ata_port *ap);
+-extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
+ extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat);
+ extern void ata_eng_timeout(struct ata_port *ap);
++extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
++			      void (*done)(struct scsi_cmnd *));
+ extern int ata_std_bios_param(struct scsi_device *sdev,
+ 			      struct block_device *bdev,
+ 			      sector_t capacity, int geom[]);
+ extern int ata_scsi_slave_config(struct scsi_device *sdev);
+ 
+ 
++#ifdef CONFIG_PCI
++struct pci_bits {
++	unsigned int		reg;	/* PCI config register to read */
++	unsigned int		width;	/* 1 (8 bit), 2 (16 bit), 4 (32 bit) */
++	unsigned long		mask;
++	unsigned long		val;
++};
++
++extern struct ata_probe_ent *
++ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port);
++extern struct ata_probe_ent *
++ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port);
++extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
++
++#endif /* CONFIG_PCI */
++
++
+ static inline unsigned int ata_tag_valid(unsigned int tag)
+ {
+ 	return (tag < ATA_MAX_QUEUE) ? 1 : 0;
+@@ -474,7 +508,6 @@
+ 
+ static inline void ata_qc_set_polling(struct ata_queued_cmd *qc)
+ {
+-	qc->flags &= ~ATA_QCFLAG_DMA;
+ 	qc->tf.ctl |= ATA_NIEN;
+ }
+ 
+@@ -602,4 +635,11 @@
+ 	return host_stat;
+ }
+ 
++static inline int ata_try_flush_cache(struct ata_device *dev)
++{
++	return ata_id_wcache_enabled(dev->id) ||
++	       ata_id_has_flush(dev->id) ||
++	       ata_id_has_flush_ext(dev->id);
++}
++
+ #endif /* __LINUX_LIBATA_H__ */
+diff -urN kernel-source-2.6.8-2.6.8.orig/include/linux/mm.h kernel-source-2.6.8-2.6.8/include/linux/mm.h
+--- kernel-source-2.6.8-2.6.8.orig/include/linux/mm.h	2006-08-11 14:32:57.045007963 -0600
++++ kernel-source-2.6.8-2.6.8/include/linux/mm.h	2006-08-11 14:32:25.501332428 -0600
+@@ -35,6 +35,8 @@
+ #define MM_VM_SIZE(mm)	TASK_SIZE
+ #endif
+ 
++#define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
++
+ /*
+  * Linux kernel virtual memory manager primitives.
+  * The idea being to have a "virtual" mm in the same way
+diff -urN kernel-source-2.6.8-2.6.8.orig/sound/oss/wavfront.c kernel-source-2.6.8-2.6.8/sound/oss/wavfront.c
+--- kernel-source-2.6.8-2.6.8.orig/sound/oss/wavfront.c	2005-05-16 12:35:54.233449000 -0600
++++ kernel-source-2.6.8-2.6.8/sound/oss/wavfront.c	2006-08-11 14:32:25.453470902 -0600
+@@ -2961,8 +2961,8 @@
+ 		if (i != cnt) {
+ 			printk (KERN_WARNING LOGNAME
+ 				"FX memset "
+-				"(0x%x, 0x%x, 0x%x, %d) incomplete\n",
+-				page, addr, (int) data, cnt);
++				"(0x%x, 0x%x, %p, %d) incomplete\n",
++				page, addr, data, cnt);
+ 			return -(EIO);
+ 		}
+ 	}
+ata-update-01.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-01.dpatch:#
+ata-update-01.dpatch:# ChangeSet
+ata-update-01.dpatch:#   2004/07/04 17:35:29-04:00 jgarzik at pobox.com 
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# drivers/scsi/ata_piix.c
+ata-update-01.dpatch:#   2004/07/04 17:35:22-04:00 jgarzik at pobox.com +51 -30
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# drivers/scsi/libata-core.c
+ata-update-01.dpatch:#   2004/07/04 17:35:23-04:00 jgarzik at pobox.com +224 -181
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# drivers/scsi/sata_nv.c
+ata-update-01.dpatch:#   2004/07/04 17:35:23-04:00 jgarzik at pobox.com +2 -0
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# drivers/scsi/sata_promise.c
+ata-update-01.dpatch:#   2004/07/04 17:35:23-04:00 jgarzik at pobox.com +5 -2
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# drivers/scsi/sata_sil.c
+ata-update-01.dpatch:#   2004/07/04 17:35:23-04:00 jgarzik at pobox.com +5 -2
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# drivers/scsi/sata_sis.c
+ata-update-01.dpatch:#   2004/07/04 17:35:23-04:00 jgarzik at pobox.com +2 -1
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# drivers/scsi/sata_svw.c
+ata-update-01.dpatch:#   2004/07/04 17:35:23-04:00 jgarzik at pobox.com +1 -0
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver pdiff -Naru a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# drivers/scsi/sata_sx4.c
+ata-update-01.dpatch:#   2004/07/04 17:35:23-04:00 jgarzik at pobox.com +3 -1
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# drivers/scsi/sata_via.c
+ata-update-01.dpatch:#   2004/07/04 17:35:23-04:00 jgarzik at pobox.com +1 -0
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# drivers/scsi/sata_vsc.c
+ata-update-01.dpatch:#   2004/07/04 17:35:23-04:00 jgarzik at pobox.com +1 -0
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# include/linux/ata.h
+ata-update-01.dpatch:#   2004/07/04 17:35:23-04:00 jgarzik at pobox.com +7 -0
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-01.dpatch:# include/linux/libata.h
+ata-update-01.dpatch:#   2004/07/04 17:35:23-04:00 jgarzik at pobox.com +15 -6
+ata-update-01.dpatch:#   [libata] transfer mode cleanup
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Add MWDMA support, and rework pio/mwdma/udma mode setup.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   In the lone test case for PATA support, ata_piix, MWDMA mode setting
+ata-update-01.dpatch:#   does not appear to work here.  UDMA and PIO continue to work, so nobody
+ata-update-01.dpatch:#   will really notice.  But beware.  Probably a driver problem, not
+ata-update-01.dpatch:#   a bug in the core.
+ata-update-01.dpatch:#   
+ata-update-01.dpatch:#   Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA
+ata-update-01.dpatch:#   anymore.
+ata-update-01.dpatch:# 
+ata-update-02.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-02.dpatch:#
+ata-update-02.dpatch:# ChangeSet
+ata-update-02.dpatch:#   2004/07/04 19:43:20-04:00 jgarzik at pobox.com 
+ata-update-02.dpatch:#   [libata] fix completion bug, better debug output
+ata-update-02.dpatch:#   
+ata-update-02.dpatch:#   When using a completion, we need to clear the entry, and furthermore
+ata-update-02.dpatch:#   clear the entry before we call the completion.
+ata-update-02.dpatch:#   
+ata-update-02.dpatch:#   Make debugging output a bit more explicit.
+ata-update-02.dpatch:# 
+ata-update-02.dpatch:# drivers/scsi/libata-core.c
+ata-update-02.dpatch:#   2004/07/04 19:43:14-04:00 jgarzik at pobox.com +10 -4
+ata-update-02.dpatch:#   [libata] fix completion bug, better debug output
+ata-update-02.dpatch:#   
+ata-update-02.dpatch:#   When using a completion, we need to clear the entry, and furthermore
+ata-update-02.dpatch:#   clear the entry before we call the completion.
+ata-update-02.dpatch:#   
+ata-update-02.dpatch:#   Make debugging output a bit more explicit.
+ata-update-02.dpatch:# 
+ata-update-03.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-03.dpatch:#
+ata-update-03.dpatch:# ChangeSet
+ata-update-03.dpatch:#   2004/07/04 19:45:33-04:00 jgarzik at pobox.com 
+ata-update-03.dpatch:#   [libata] convert set-xfer-mode operation to use ata_queued_cmd
+ata-update-03.dpatch:# 
+ata-update-03.dpatch:# drivers/scsi/libata-core.c
+ata-update-03.dpatch:#   2004/07/04 19:45:27-04:00 jgarzik at pobox.com +27 -17
+ata-update-03.dpatch:#   [libata] convert set-xfer-mode operation to use ata_queued_cmd
+ata-update-03.dpatch:# 
+ata-update-04.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-04.dpatch:#
+ata-update-04.dpatch:# ChangeSet
+ata-update-04.dpatch:#   2004/07/04 21:02:36-04:00 jgarzik at pobox.com 
+ata-update-04.dpatch:#   [libata] transfer mode bug fixes and type cleanup
+ata-update-04.dpatch:#   
+ata-update-04.dpatch:#   Fix two bugs that causes the recently-added transfer mode code
+ata-update-04.dpatch:#   to break on 64-bit platforms.  Make associated code more type-correct
+ata-update-04.dpatch:#   in the process.
+ata-update-04.dpatch:# 
+ata-update-04.dpatch:# drivers/scsi/libata-core.c
+ata-update-04.dpatch:#   2004/07/04 21:02:31-04:00 jgarzik at pobox.com +33 -21
+ata-update-04.dpatch:#   [libata] transfer mode bug fixes and type cleanup
+ata-update-04.dpatch:#   
+ata-update-04.dpatch:#   Fix two bugs that causes the recently-added transfer mode code
+ata-update-04.dpatch:#   to break on 64-bit platforms.  Make associated code more type-correct
+ata-update-04.dpatch:#   in the process.
+ata-update-04.dpatch:# 
+ata-update-04.dpatch:# include/linux/libata.h
+ata-update-04.dpatch:#   2004/07/04 21:02:31-04:00 jgarzik at pobox.com +3 -3
+ata-update-04.dpatch:#   [libata] transfer mode bug fixes and type cleanup
+ata-update-04.dpatch:#   
+ata-update-04.dpatch:#   Fix two bugs that causes the recently-added transfer mode code
+ata-update-04.dpatch:#   to break on 64-bit platforms.  Make associated code more type-correct
+ata-update-04.dpatch:#   in the process.
+ata-update-04.dpatch:# 
+ata-update-05.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-05.dpatch:#
+ata-update-05.dpatch:# ChangeSet
+ata-update-05.dpatch:#   2004/07/04 23:40:44-04:00 jgarzik at pobox.com 
+ata-update-05.dpatch:#   [libata sata_promise] convert to using packets for non-data taskfiles
+ata-update-05.dpatch:# 
+ata-update-05.dpatch:# drivers/scsi/sata_promise.c
+ata-update-05.dpatch:#   2004/07/04 23:40:38-04:00 jgarzik at pobox.com +27 -41
+ata-update-05.dpatch:#   [libata sata_promise] convert to using packets for non-data taskfiles
+ata-update-05.dpatch:# 
+ata-update-06.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-06.dpatch:#
+ata-update-06.dpatch:# ChangeSet
+ata-update-06.dpatch:#   2004/07/05 21:53:56-04:00 jgarzik at pobox.com 
+ata-update-06.dpatch:#   [libata sata_sx4] deliver non-data taskfiles using Promise packet format
+ata-update-06.dpatch:# 
+ata-update-06.dpatch:# drivers/scsi/sata_promise.c
+ata-update-06.dpatch:#   2004/07/05 21:53:50-04:00 jgarzik at pobox.com +1 -1
+ata-update-06.dpatch:#   [libata sata_sx4] deliver non-data taskfiles using Promise packet format
+ata-update-06.dpatch:# 
+ata-update-06.dpatch:# drivers/scsi/sata_sx4.c
+ata-update-06.dpatch:#   2004/07/05 21:53:50-04:00 jgarzik at pobox.com +97 -64
+ata-update-06.dpatch:#   [libata sata_sx4] deliver non-data taskfiles using Promise packet format
+ata-update-06.dpatch:# 
+ata-update-07.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-07.dpatch:#
+ata-update-07.dpatch:# ChangeSet
+ata-update-07.dpatch:#   2004/07/07 15:51:57-04:00 jgarzik at pobox.com 
+ata-update-07.dpatch:#   [libata] pio/dma flag bug fix, and cleanup
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   In the transfer-mode cleanup recently, the code that set flag
+ata-update-07.dpatch:#   ATA_DFLAG_PIO disappeared.  Resurrect it.
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   Remove ATA_QCFLAG_DMA, it isn't needed.
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   Always set polling in the ->qc_issue function, rather than force
+ata-update-07.dpatch:#   the user to do it when setting up an ata_queued_cmd.  This gives
+ata-update-07.dpatch:#   maximum flexibility to the driver, letting the driver choose
+ata-update-07.dpatch:#   whether or not to poll.
+ata-update-07.dpatch:# 
+ata-update-07.dpatch:# drivers/scsi/libata-core.c
+ata-update-07.dpatch:#   2004/07/07 15:51:50-04:00 jgarzik at pobox.com +4 -2
+ata-update-07.dpatch:#   [libata] pio/dma flag bug fix, and cleanup
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   In the transfer-mode cleanup recently, the code that set flag
+ata-update-07.dpatch:#   ATA_DFLAG_PIO disappeared.  Resurrect it.
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   Remove ATA_QCFLAG_DMA, it isn't needed.
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   Always set polling in the ->qc_issue function, rather than force
+ata-update-07.dpatch:#   the user to do it when setting up an ata_queued_cmd.  This gives
+ata-update-07.dpatch:#   maximum flexibility to the driver, letting the driver choose
+ata-update-07.dpatch:#   whether or not to poll.
+ata-update-07.dpatch:# 
+ata-update-07.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-07.dpatch:#   2004/07/07 15:51:50-04:00 jgarzik at pobox.com +5 -4
+ata-update-07.dpatch:#   [libata] pio/dma flag bug fix, and cleanup
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   In the transfer-mode cleanup recently, the code that set flag
+ata-update-07.dpatch:#   ATA_DFLAG_PIO disappeared.  Resurrect it.
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   Remove ATA_QCFLAG_DMA, it isn't needed.
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   Always set polling in the ->qc_issue function, rather than force
+ata-update-07.dpatch:#   the user to do it when setting up an ata_queued_cmd.  This gives
+ata-update-07.dpatch:#   maximum flexibility to the driver, letting the driver choose
+ata-update-07.dpatch:#   whether or not to poll.
+ata-update-07.dpatch:# 
+ata-update-07.dpatch:# include/linux/libata.h
+ata-update-07.dpatch:#   2004/07/07 15:51:50-04:00 jgarzik at pobox.com +0 -2
+ata-update-07.dpatch:#   [libata] pio/dma flag bug fix, and cleanup
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   In the transfer-mode cleanup recently, the code that set flag
+ata-update-07.dpatch:#   ATA_DFLAG_PIO disappeared.  Resurrect it.
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   Remove ATA_QCFLAG_DMA, it isn't needed.
+ata-update-07.dpatch:#   
+ata-update-07.dpatch:#   Always set polling in the ->qc_issue function, rather than force
+ata-update-07.dpatch:#   the user to do it when setting up an ata_queued_cmd.  This gives
+ata-update-07.dpatch:#   maximum flexibility to the driver, letting the driver choose
+ata-update-07.dpatch:#   whether or not to poll.
+ata-update-07.dpatch:# 
+ata-update-08.dpatch:# backported to Debian's 2.6.8 by dann frazier <dannf at hp.com>
+ata-update-08.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-08.dpatch:#
+ata-update-08.dpatch:# ChangeSet
+ata-update-08.dpatch:#   2004/07/07 17:14:55-04:00 jgarzik at pobox.com 
+ata-update-08.dpatch:#   [libata] update IDENTIFY DEVICE path to use ata_queued_cmd
+ata-update-08.dpatch:#   
+ata-update-08.dpatch:#   rather than hand-rolling our own taskfile call (which won't work at
+ata-update-08.dpatch:#   all on newer SATA controllers).
+ata-update-08.dpatch:#   
+ata-update-08.dpatch:#   Individual changes:
+ata-update-08.dpatch:#   * use ata_qc_issue to issue identify-device command
+ata-update-08.dpatch:#   * implement MMIO path for PIO data xfer
+ata-update-08.dpatch:#   * implement PIO error handling path
+ata-update-08.dpatch:# 
+ata-update-08.dpatch:# drivers/scsi/libata-core.c
+ata-update-08.dpatch:#   2004/07/07 17:14:48-04:00 jgarzik at pobox.com +72 -62
+ata-update-08.dpatch:#   [libata] update IDENTIFY DEVICE path to use ata_queued_cmd
+ata-update-08.dpatch:#   
+ata-update-08.dpatch:#   rather than hand-rolling our own taskfile call (which won't work at
+ata-update-08.dpatch:#   all on newer SATA controllers).
+ata-update-08.dpatch:#   
+ata-update-08.dpatch:#   Individual changes:
+ata-update-08.dpatch:#   * use ata_qc_issue to issue identify-device command
+ata-update-08.dpatch:#   * implement MMIO path for PIO data xfer
+ata-update-08.dpatch:#   * implement PIO error handling path
+ata-update-08.dpatch:# 
+ata-update-09.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-09.dpatch:#
+ata-update-09.dpatch:# ChangeSet
+ata-update-09.dpatch:#   2004/07/09 23:20:04-04:00 jgarzik at pobox.com 
+ata-update-09.dpatch:#   [libata] ATAPI work - PIO xfer, completion function
+ata-update-09.dpatch:#   
+ata-update-09.dpatch:#   Move hand-coded ATA Data register I/O from ata_pio_sector() to its
+ata-update-09.dpatch:#   own function ata_data_xfer(), so that it may also be used to send the
+ata-update-09.dpatch:#   ATAPI packet to hardware.
+ata-update-09.dpatch:#   
+ata-update-09.dpatch:#   Use ata_data_xfer() in ATAPI packet send.
+ata-update-09.dpatch:#   
+ata-update-09.dpatch:#   Separate ATA and ATAPI completion functions.
+ata-update-09.dpatch:# 
+ata-update-09.dpatch:# drivers/scsi/libata-core.c
+ata-update-09.dpatch:#   2004/07/09 23:19:57-04:00 jgarzik at pobox.com +41 -22
+ata-update-09.dpatch:#   [libata] ATAPI work - PIO xfer, completion function
+ata-update-09.dpatch:#   
+ata-update-09.dpatch:#   Move hand-coded ATA Data register I/O from ata_pio_sector() to its
+ata-update-09.dpatch:#   own function ata_data_xfer(), so that it may also be used to send the
+ata-update-09.dpatch:#   ATAPI packet to hardware.
+ata-update-09.dpatch:#   
+ata-update-09.dpatch:#   Use ata_data_xfer() in ATAPI packet send.
+ata-update-09.dpatch:#   
+ata-update-09.dpatch:#   Separate ATA and ATAPI completion functions.
+ata-update-09.dpatch:# 
+ata-update-09.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-09.dpatch:#   2004/07/09 23:19:58-04:00 jgarzik at pobox.com +30 -7
+ata-update-09.dpatch:#   [libata] ATAPI work - PIO xfer, completion function
+ata-update-09.dpatch:#   
+ata-update-09.dpatch:#   Move hand-coded ATA Data register I/O from ata_pio_sector() to its
+ata-update-09.dpatch:#   own function ata_data_xfer(), so that it may also be used to send the
+ata-update-09.dpatch:#   ATAPI packet to hardware.
+ata-update-09.dpatch:#   
+ata-update-09.dpatch:#   Use ata_data_xfer() in ATAPI packet send.
+ata-update-09.dpatch:#   
+ata-update-09.dpatch:#   Separate ATA and ATAPI completion functions.
+ata-update-09.dpatch:# 
+ata-update-10.dpatch:# backported to Debian's 2.6.8 by dann frazier <dannf at hp.com>
+ata-update-10.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-10.dpatch:#
+ata-update-10.dpatch:# ChangeSet
+ata-update-10.dpatch:#   2004/07/10 11:09:17-04:00 jgarzik at pobox.com 
+ata-update-10.dpatch:#   [libata] flags cleanup
+ata-update-10.dpatch:#   
+ata-update-10.dpatch:#   Remove unused/redundant flags ATA_DFLAG_{MASTER,WCACHE}
+ata-update-10.dpatch:# 
+ata-update-10.dpatch:# drivers/scsi/ata_piix.c
+ata-update-10.dpatch:#   2004/07/10 11:09:11-04:00 jgarzik at pobox.com +1 -1
+ata-update-10.dpatch:#   [libata] flags cleanup
+ata-update-10.dpatch:#   
+ata-update-10.dpatch:#   Remove unused/redundant flags ATA_DFLAG_{MASTER,WCACHE}
+ata-update-10.dpatch:# 
+ata-update-10.dpatch:# drivers/scsi/libata-core.c
+ata-update-10.dpatch:#   2004/07/10 11:09:11-04:00 jgarzik at pobox.com +0 -1
+ata-update-10.dpatch:#   [libata] flags cleanup
+ata-update-10.dpatch:#   
+ata-update-10.dpatch:#   Remove unused/redundant flags ATA_DFLAG_{MASTER,WCACHE}
+ata-update-10.dpatch:# 
+ata-update-10.dpatch:# include/linux/libata.h
+ata-update-10.dpatch:#   2004/07/10 11:09:11-04:00 jgarzik at pobox.com +1 -4
+ata-update-10.dpatch:#   [libata] flags cleanup
+ata-update-10.dpatch:#   
+ata-update-10.dpatch:#   Remove unused/redundant flags ATA_DFLAG_{MASTER,WCACHE}
+ata-update-10.dpatch:# 
+ata-update-11.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-11.dpatch:#
+ata-update-11.dpatch:# ChangeSet
+ata-update-11.dpatch:#   2004/07/10 12:47:34-04:00 jgarzik at pobox.com 
+ata-update-11.dpatch:#   [libata] ATAPI work - cdb len, new taskfile protocol, cleanups
+ata-update-11.dpatch:#   
+ata-update-11.dpatch:#   * new helper atapi_cdb_len() in linux/ata.h, use it after
+ata-update-11.dpatch:#   IDENTIFY PACKET DEVICE command completes
+ata-update-11.dpatch:#   * add new taskfile protocol ATA_PROT_ATAPI_NODATA
+ata-update-11.dpatch:#   * store scsi cdb in ata_queued_cmd.  This removes another dependence
+ata-update-11.dpatch:#   on the scsi layer, and enables us to issue an internal REQUEST SENSE.
+ata-update-11.dpatch:#   * store cdb len in ata_port
+ata-update-11.dpatch:#   * new constant ATAPI_CDB_LEN for max cdb length
+ata-update-11.dpatch:#   * move ATA taskfile and SCSI cdb near the top of ata_queued_cmd, for
+ata-update-11.dpatch:#   better cacheline friendliness.
+ata-update-11.dpatch:# 
+ata-update-11.dpatch:# drivers/scsi/libata-core.c
+ata-update-11.dpatch:#   2004/07/10 12:47:28-04:00 jgarzik at pobox.com +17 -8
+ata-update-11.dpatch:#   [libata] ATAPI work - cdb len, new taskfile protocol, cleanups
+ata-update-11.dpatch:#   
+ata-update-11.dpatch:#   * new helper atapi_cdb_len() in linux/ata.h, use it after
+ata-update-11.dpatch:#   IDENTIFY PACKET DEVICE command completes
+ata-update-11.dpatch:#   * add new taskfile protocol ATA_PROT_ATAPI_NODATA
+ata-update-11.dpatch:#   * store scsi cdb in ata_queued_cmd.  This removes another dependence
+ata-update-11.dpatch:#   on the scsi layer, and enables us to issue an internal REQUEST SENSE.
+ata-update-11.dpatch:#   * store cdb len in ata_port
+ata-update-11.dpatch:#   * new constant ATAPI_CDB_LEN for max cdb length
+ata-update-11.dpatch:#   * move ATA taskfile and SCSI cdb near the top of ata_queued_cmd, for
+ata-update-11.dpatch:#   better cacheline friendliness.
+ata-update-11.dpatch:# 
+ata-update-11.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-11.dpatch:#   2004/07/10 12:47:28-04:00 jgarzik at pobox.com +11 -8
+ata-update-11.dpatch:#   [libata] ATAPI work - cdb len, new taskfile protocol, cleanups
+ata-update-11.dpatch:#   
+ata-update-11.dpatch:#   * new helper atapi_cdb_len() in linux/ata.h, use it after
+ata-update-11.dpatch:#   IDENTIFY PACKET DEVICE command completes
+ata-update-11.dpatch:#   * add new taskfile protocol ATA_PROT_ATAPI_NODATA
+ata-update-11.dpatch:#   * store scsi cdb in ata_queued_cmd.  This removes another dependence
+ata-update-11.dpatch:#   on the scsi layer, and enables us to issue an internal REQUEST SENSE.
+ata-update-11.dpatch:#   * store cdb len in ata_port
+ata-update-11.dpatch:#   * new constant ATAPI_CDB_LEN for max cdb length
+ata-update-11.dpatch:#   * move ATA taskfile and SCSI cdb near the top of ata_queued_cmd, for
+ata-update-11.dpatch:#   better cacheline friendliness.
+ata-update-11.dpatch:# 
+ata-update-11.dpatch:# include/linux/ata.h
+ata-update-11.dpatch:#   2004/07/10 12:47:28-04:00 jgarzik at pobox.com +14 -1
+ata-update-11.dpatch:#   [libata] ATAPI work - cdb len, new taskfile protocol, cleanups
+ata-update-11.dpatch:#   
+ata-update-11.dpatch:#   * new helper atapi_cdb_len() in linux/ata.h, use it after
+ata-update-11.dpatch:#   IDENTIFY PACKET DEVICE command completes
+ata-update-11.dpatch:#   * add new taskfile protocol ATA_PROT_ATAPI_NODATA
+ata-update-11.dpatch:#   * store scsi cdb in ata_queued_cmd.  This removes another dependence
+ata-update-11.dpatch:#   on the scsi layer, and enables us to issue an internal REQUEST SENSE.
+ata-update-11.dpatch:#   * store cdb len in ata_port
+ata-update-11.dpatch:#   * new constant ATAPI_CDB_LEN for max cdb length
+ata-update-11.dpatch:#   * move ATA taskfile and SCSI cdb near the top of ata_queued_cmd, for
+ata-update-11.dpatch:#   better cacheline friendliness.
+ata-update-11.dpatch:# 
+ata-update-11.dpatch:# include/linux/libata.h
+ata-update-11.dpatch:#   2004/07/10 12:47:28-04:00 jgarzik at pobox.com +4 -1
+ata-update-11.dpatch:#   [libata] ATAPI work - cdb len, new taskfile protocol, cleanups
+ata-update-11.dpatch:#   
+ata-update-11.dpatch:#   * new helper atapi_cdb_len() in linux/ata.h, use it after
+ata-update-11.dpatch:#   IDENTIFY PACKET DEVICE command completes
+ata-update-11.dpatch:#   * add new taskfile protocol ATA_PROT_ATAPI_NODATA
+ata-update-11.dpatch:#   * store scsi cdb in ata_queued_cmd.  This removes another dependence
+ata-update-11.dpatch:#   on the scsi layer, and enables us to issue an internal REQUEST SENSE.
+ata-update-11.dpatch:#   * store cdb len in ata_port
+ata-update-11.dpatch:#   * new constant ATAPI_CDB_LEN for max cdb length
+ata-update-11.dpatch:#   * move ATA taskfile and SCSI cdb near the top of ata_queued_cmd, for
+ata-update-11.dpatch:#   better cacheline friendliness.
+ata-update-11.dpatch:# 
+ata-update-12.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-12.dpatch:#
+ata-update-12.dpatch:# ChangeSet
+ata-update-12.dpatch:#   2004/08/13 23:47:03-04:00 jgarzik at pobox.com 
+ata-update-12.dpatch:#   [libata] (cosmetic) minimize diff with 2.4.x libata
+ata-update-12.dpatch:#   
+ata-update-12.dpatch:#   Also, remove BenH's email address from SiI driver, to reduce
+ata-update-12.dpatch:#   email coming to him for a driver he didn't write (by request).
+ata-update-12.dpatch:# 
+ata-update-12.dpatch:# drivers/scsi/sata_sil.c
+ata-update-12.dpatch:#   2004/08/13 23:46:10-04:00 jgarzik at pobox.com +1 -1
+ata-update-12.dpatch:#   [libata] (cosmetic) minimize diff with 2.4.x libata
+ata-update-12.dpatch:#   
+ata-update-12.dpatch:#   Also, remove BenH's email address from SiI driver, to reduce
+ata-update-12.dpatch:#   email coming to him for a driver he didn't write (by request).
+ata-update-12.dpatch:# 
+ata-update-12.dpatch:# drivers/scsi/sata_sis.c
+ata-update-12.dpatch:#   2004/08/13 23:46:10-04:00 jgarzik at pobox.com +1 -1
+ata-update-12.dpatch:#   [libata] (cosmetic) minimize diff with 2.4.x libata
+ata-update-12.dpatch:#   
+ata-update-12.dpatch:#   Also, remove BenH's email address from SiI driver, to reduce
+ata-update-12.dpatch:#   email coming to him for a driver he didn't write (by request).
+ata-update-12.dpatch:# 
+ata-update-12.dpatch:# drivers/scsi/sata_svw.c
+ata-update-12.dpatch:#   2004/08/13 23:46:10-04:00 jgarzik at pobox.com +1 -0
+ata-update-12.dpatch:#   [libata] (cosmetic) minimize diff with 2.4.x libata
+ata-update-12.dpatch:#   
+ata-update-12.dpatch:#   Also, remove BenH's email address from SiI driver, to reduce
+ata-update-12.dpatch:#   email coming to him for a driver he didn't write (by request).
+ata-update-12.dpatch:# 
+ata-update-13.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-13.dpatch:#
+ata-update-13.dpatch:# ChangeSet
+ata-update-13.dpatch:#   2004/08/14 07:39:52-04:00 jgarzik at pobox.com 
+ata-update-13.dpatch:#   [libata] support commands SYNCHRONIZE CACHE, VERIFY, VERIFY(16)
+ata-update-13.dpatch:# 
+ata-update-13.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-13.dpatch:#   2004/08/14 07:38:42-04:00 jgarzik at pobox.com +132 -7
+ata-update-13.dpatch:#   [libata] support commands SYNCHRONIZE CACHE, VERIFY, VERIFY(16)
+ata-update-13.dpatch:# 
+ata-update-13.dpatch:# include/linux/ata.h
+ata-update-13.dpatch:#   2004/08/14 07:38:42-04:00 jgarzik at pobox.com +2 -0
+ata-update-13.dpatch:#   [libata] support commands SYNCHRONIZE CACHE, VERIFY, VERIFY(16)
+ata-update-13.dpatch:# 
+ata-update-13.dpatch:# include/linux/libata.h
+ata-update-13.dpatch:#   2004/08/14 07:38:42-04:00 jgarzik at pobox.com +7 -0
+ata-update-13.dpatch:#   [libata] support commands SYNCHRONIZE CACHE, VERIFY, VERIFY(16)
+ata-update-13.dpatch:# 
+ata-update-13.dpatch:# include/scsi/scsi.h
+ata-update-13.dpatch:#   2004/08/14 07:38:42-04:00 jgarzik at pobox.com +1 -0
+ata-update-13.dpatch:#   [libata] support commands SYNCHRONIZE CACHE, VERIFY, VERIFY(16)
+ata-update-13.dpatch:# 
+ata-update-14.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-14.dpatch:#
+ata-update-14.dpatch:# ChangeSet
+ata-update-14.dpatch:#   2004/08/14 09:50:36-04:00 jgarzik at pobox.com 
+ata-update-14.dpatch:#   [libata] fix PIO data xfer on big endian
+ata-update-14.dpatch:#   
+ata-update-14.dpatch:#   We were reading the data swapped, which was correct for the
+ata-update-14.dpatch:#   data page read from IDENTIFY DEVICE and incorrect for all other
+ata-update-14.dpatch:#   situations.
+ata-update-14.dpatch:#   
+ata-update-14.dpatch:#   Noticed by Ben Herrenschmidt.
+ata-update-14.dpatch:# 
+ata-update-14.dpatch:# drivers/scsi/libata-core.c
+ata-update-14.dpatch:#   2004/08/14 09:50:29-04:00 jgarzik at pobox.com +19 -5
+ata-update-14.dpatch:#   [libata] fix PIO data xfer on big endian
+ata-update-14.dpatch:#   
+ata-update-14.dpatch:#   We were reading the data swapped, which was correct for the
+ata-update-14.dpatch:#   data page read from IDENTIFY DEVICE and incorrect for all other
+ata-update-14.dpatch:#   situations.
+ata-update-14.dpatch:#   
+ata-update-14.dpatch:#   Noticed by Ben Herrenschmidt.
+ata-update-14.dpatch:# 
+ata-update-15.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-15.dpatch:#
+ata-update-15.dpatch:# ChangeSet
+ata-update-15.dpatch:#   2004/08/14 10:13:29-04:00 jgarzik at pobox.com 
+ata-update-15.dpatch:#   [libata] ATAPI PIO data xfer
+ata-update-15.dpatch:#   
+ata-update-15.dpatch:#   Abstract out PIO data xfer to xfer-a-sector and other-stuff pieces,
+ata-update-15.dpatch:#   then add new ATAPI code that uses the common xfer-a-sector code.
+ata-update-15.dpatch:# 
+ata-update-15.dpatch:# drivers/scsi/libata-core.c
+ata-update-15.dpatch:#   2004/08/14 10:13:23-04:00 jgarzik at pobox.com +81 -32
+ata-update-15.dpatch:#   [libata] ATAPI PIO data xfer
+ata-update-15.dpatch:#   
+ata-update-15.dpatch:#   Abstract out PIO data xfer to xfer-a-sector and other-stuff pieces,
+ata-update-15.dpatch:#   then add new ATAPI code that uses the common xfer-a-sector code.
+ata-update-15.dpatch:# 
+ata-update-16.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-16.dpatch:#
+ata-update-16.dpatch:# ChangeSet
+ata-update-16.dpatch:#   2004/08/14 15:38:01-04:00 jgarzik at pobox.com 
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/ata_piix.c
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +1 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/libata-core.c
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +2 -2
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +51 -9
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/libata.h
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +1 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/sata_nv.c
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +1 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/sata_promise.c
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +1 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/sata_sil.c
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +1 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/sata_sis.c
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +1 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/sata_svw.c
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +1 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/sata_sx4.c
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +1 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/sata_via.c
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +1 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# drivers/scsi/sata_vsc.c
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +1 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# include/linux/ata.h
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +5 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_3diff -Naru a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
+ata-update-16.dpatch:# 
+ata-update-16.dpatch:# include/linux/libata.h
+ata-update-16.dpatch:#   2004/08/14 15:37:54-04:00 jgarzik at pobox.com +1 -0
+ata-update-16.dpatch:#   [libata] add ioctl infrastructure
+ata-update-16.dpatch:#   
+ata-update-16.dpatch:#   Mainly adding the infrastructure for various ATA ioctls.  Currently
+ata-update-16.dpatch:#   only supports two ATA-specific ioctls:
+ata-update-16.dpatch:#   HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
+ata-update-16.dpatch:# 
+ata-update-17.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-17.dpatch:#
+ata-update-17.dpatch:# ChangeSet
+ata-update-17.dpatch:#   2004/08/16 12:31:46-04:00 akpm at osdl.org 
+ata-update-17.dpatch:#   [PATCH] libata build fix
+ata-update-17.dpatch:#   
+ata-update-17.dpatch:#   drivers/scsi/libata-core.c: In function `swap_buf_le16':
+ata-update-17.dpatch:#   drivers/scsi/libata-core.c:2073: `words' undeclared (first use in this function)
+ata-update-17.dpatch:#   drivers/scsi/libata-core.c:2073: (Each undeclared identifier is reported only once
+ata-update-17.dpatch:#   
+ata-update-17.dpatch:#   Signed-off-by: Andrew Morton <akpm at osdl.org>
+ata-update-17.dpatch:# 
+ata-update-17.dpatch:# drivers/scsi/libata-core.c
+ata-update-17.dpatch:#   2004/08/16 02:35:24-04:00 akpm at osdl.org +1 -1
+ata-update-17.dpatch:#   libata build fix
+ata-update-17.dpatch:# 
+ata-update-18.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-18.dpatch:#
+ata-update-18.dpatch:# ChangeSet
+ata-update-18.dpatch:#   2004/08/18 01:47:29-04:00 jgarzik at pobox.com 
+ata-update-18.dpatch:#   [ata] remove 'packed' attributed from struct ata_prd
+ata-update-18.dpatch:#   
+ata-update-18.dpatch:#   It's not needed, and it generates very poor code on some platforms.
+ata-update-18.dpatch:#   
+ata-update-18.dpatch:#   Noticed by Bart and David Miller.
+ata-update-18.dpatch:# 
+ata-update-18.dpatch:# include/linux/ata.h
+ata-update-18.dpatch:#   2004/08/18 01:47:22-04:00 jgarzik at pobox.com +1 -1
+ata-update-18.dpatch:#   [ata] remove 'packed' attributed from struct ata_prd
+ata-update-18.dpatch:#   
+ata-update-18.dpatch:#   It's not needed, and it generates very poor code on some platforms.
+ata-update-18.dpatch:#   
+ata-update-18.dpatch:#   Noticed by Bart and David Miller.
+ata-update-18.dpatch:# 
+ata-update-19.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-19.dpatch:#
+ata-update-19.dpatch:# ChangeSet
+ata-update-19.dpatch:#   2004/08/18 01:51:52-04:00 alan at redhat.com 
+ata-update-19.dpatch:#   [libata] improve translation of ATA errors to SCSI sense codes
+ata-update-19.dpatch:# 
+ata-update-19.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-19.dpatch:#   2004/08/18 01:51:45-04:00 alan at redhat.com +141 -17
+ata-update-19.dpatch:#   [libata] improve translation of ATA errors to SCSI sense codes
+ata-update-19.dpatch:# 
+ata-update-19.dpatch:# drivers/scsi/libata.h
+ata-update-19.dpatch:#   2004/08/18 01:51:45-04:00 alan at redhat.com +1 -1
+ata-update-19.dpatch:#   [libata] improve translation of ATA errors to SCSI sense codes
+ata-update-19.dpatch:# 
+ata-update-20.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-20.dpatch:#
+ata-update-20.dpatch:# ChangeSet
+ata-update-20.dpatch:#   2004/08/18 20:39:03-04:00 achew at nvidia.com 
+ata-update-20.dpatch:#   [libata sata_nv] fix leak on error
+ata-update-20.dpatch:#   
+ata-update-20.dpatch:#   Spotted by Francois Romieu.
+ata-update-20.dpatch:# 
+ata-update-20.dpatch:# drivers/scsi/sata_nv.c
+ata-update-20.dpatch:#   2004/08/18 14:24:40-04:00 achew at nvidia.com +6 -2
+ata-update-20.dpatch:#   2.6.8-rc libata fixes]
+ata-update-20.dpatch:# 
+ata-update-21.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-21.dpatch:#
+ata-update-21.dpatch:# ChangeSet
+ata-update-21.dpatch:#   2004/08/28 19:02:49-04:00 jeremy at sgi.com 
+ata-update-21.dpatch:#   [PATCH] Fix DMA boundary overflow bug
+ata-update-21.dpatch:#   
+ata-update-21.dpatch:#   We seem to have found an overflow problem in libata-core.c.
+ata-update-21.dpatch:#   We were trying to DMA to the address range 0xffff8000-0xffffbfff.
+ata-update-21.dpatch:#   
+ata-update-21.dpatch:#   In the original version of the code, given that address and
+ata-update-21.dpatch:#   count (0xffff8000 and 0x4000), the variable "boundary" would be
+ata-update-21.dpatch:#   set to 0, causing len to be set to 0x8000 (which is greater than
+ata-update-21.dpatch:#   sg_len).  Then at the bottom of the loop, sg_len would be set
+ata-update-21.dpatch:#   to 0xffffc000 (0x4000 - 0x8000), which would then cause the
+ata-update-21.dpatch:#   loop never to terminate (until much of memory was scribbled
+ata-update-21.dpatch:#   over or the kernel died).
+ata-update-21.dpatch:#   
+ata-update-21.dpatch:#   The code below should be functionally identical, but not be
+ata-update-21.dpatch:#   subject to the same overflow problem (boundary needs to be a
+ata-update-21.dpatch:#   u33).
+ata-update-21.dpatch:#   
+ata-update-21.dpatch:#   Signed-off-by: jeremy at sgi.com
+ata-update-21.dpatch:#   
+ata-update-21.dpatch:#   ===== drivers/scsi/libata-core.c 1.94 vs edited =====
+ata-update-21.dpatch:# 
+ata-update-21.dpatch:# drivers/scsi/libata-core.c
+ata-update-21.dpatch:#   2004/08/26 00:10:45-04:00 jeremy at sgi.com +4 -4
+ata-update-21.dpatch:#   2.6.9-rc1  drivers/scsi/libata-core.c
+ata-update-21.dpatch:# 
+ata-update-22.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-22.dpatch:#
+ata-update-22.dpatch:# ChangeSet
+ata-update-22.dpatch:#   2004/08/28 19:29:32-04:00 achew at nvidia.com 
+ata-update-22.dpatch:#   [PATCH] sata_nv: fix CK804 support
+ata-update-22.dpatch:#   
+ata-update-22.dpatch:#   This patch fixes a problem introduced when CK804 support was added.  mmio_base can only be set in the CK804 case,
+ata-update-22.dpatch:#   else libata will attempt to iounmap mmio_base, which isn't iomapped for the non-CK804 case.  Still need the bar 5
+ata-update-22.dpatch:#   address, so steal from host_set->ports[0]->ioaddr.scr_addr.  Jeff, let me know if this is a bad thing to do.
+ata-update-22.dpatch:# 
+ata-update-22.dpatch:# drivers/scsi/sata_nv.c
+ata-update-22.dpatch:#   2004/08/19 16:36:06-04:00 achew at nvidia.com +12 -8
+ata-update-22.dpatch:#   sata_nv.c
+ata-update-22.dpatch:# 
+ata-update-23.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-23.dpatch:#
+ata-update-23.dpatch:# ChangeSet
+ata-update-23.dpatch:#   2004/08/30 14:43:27-04:00 bzolnier at elka.pw.edu.pl 
+ata-update-23.dpatch:#   [PATCH] libata: ata_piix.c PIO fix
+ata-update-23.dpatch:#   
+ata-update-23.dpatch:#   [patch] libata: ata_piix.c PIO fix
+ata-update-23.dpatch:#   
+ata-update-23.dpatch:#   "[libata] transfer mode cleanup" introduced bug in ata_piix.c:
+ata-update-23.dpatch:#   previously PIO number (not mode) was passed to piix_set_piomode().
+ata-update-23.dpatch:#   Fortunately this function is only used for (disabled) PATA support.
+ata-update-23.dpatch:#   
+ata-update-23.dpatch:#   I bet that this is the reason why MWDMA didn't work for PATA.
+ata-update-23.dpatch:#   
+ata-update-23.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at elka.pw.edu.pl>
+ata-update-23.dpatch:# 
+ata-update-23.dpatch:# drivers/scsi/ata_piix.c
+ata-update-23.dpatch:#   2004/08/30 14:23:18-04:00 bzolnier at elka.pw.edu.pl +1 -1
+ata-update-23.dpatch:#   libata: ata_piix.c PIO fix
+ata-update-23.dpatch:# 
+ata-update-24.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-24.dpatch:#
+ata-update-24.dpatch:# ChangeSet
+ata-update-24.dpatch:#   2004/09/10 13:27:57-04:00 janitor at sternwelten.at 
+ata-update-24.dpatch:#   [PATCH] scsi/sata_sx4: replace schedule_timeout() 	with
+ata-update-24.dpatch:#   
+ata-update-24.dpatch:#   Use msleep() instead of schedule_timeout() to
+ata-update-24.dpatch:#   guarantee the task delays for the desired time.
+ata-update-24.dpatch:#   
+ata-update-24.dpatch:#   Signed-off-by: Nishanth Aravamudan <nacc at us.ibm.com>
+ata-update-24.dpatch:#   Signed-off-by: Maximilian Attems <janitor at sternwelten.at>
+ata-update-24.dpatch:#   Signed-off-by: James Bottomley <James.Bottomley at SteelEye.com>
+ata-update-24.dpatch:# 
+ata-update-24.dpatch:# drivers/scsi/sata_sx4.c
+ata-update-24.dpatch:#   2004/09/01 13:35:48-04:00 janitor at sternwelten.at +2 -4
+ata-update-24.dpatch:#   scsi/sata_sx4: replace schedule_timeout() 	with
+ata-update-24.dpatch:# 
+ata-update-25.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-25.dpatch:#
+ata-update-25.dpatch:# ChangeSet
+ata-update-25.dpatch:#   2004/10/28 08:18:25-07:00 jgarzik at pobox.com 
+ata-update-25.dpatch:#   [PATCH] add nth_page()
+ata-update-25.dpatch:#   
+ata-update-25.dpatch:#   Provide a function to get the pageframe number of the nth page at
+ata-update-25.dpatch:#   scatterlist.page.  We cannot just index off scatterlist.page because the
+ata-update-25.dpatch:#   physically-contiguous pages may not be contiguous in mem_map[].
+ata-update-25.dpatch:#   
+ata-update-25.dpatch:#   Signed-off-by: Andrew Morton <akpm at osdl.org>
+ata-update-25.dpatch:#   Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+ata-update-25.dpatch:# 
+ata-update-25.dpatch:# include/linux/mm.h
+ata-update-25.dpatch:#   2004/10/28 00:56:39-07:00 jgarzik at pobox.com +2 -0
+ata-update-25.dpatch:#   add nth_page()
+ata-update-25.dpatch:# 
+ata-update-26.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-26.dpatch:#
+ata-update-26.dpatch:# ChangeSet
+ata-update-26.dpatch:#   2004/09/13 22:14:43-04:00 jgarzik at pobox.com 
+ata-update-26.dpatch:#   [libata sata_nv] sync with 2.4
+ata-update-26.dpatch:#   
+ata-update-26.dpatch:#   Driver should be using LIBATA_MAX_PRD not ATA_MAX_PRD,
+ata-update-26.dpatch:#   due to iommu layer splitting.
+ata-update-26.dpatch:# 
+ata-update-26.dpatch:# drivers/scsi/sata_nv.c
+ata-update-26.dpatch:#   2004/09/13 22:14:35-04:00 jgarzik at pobox.com +1 -1
+ata-update-26.dpatch:#   [libata sata_nv] sync with 2.4
+ata-update-26.dpatch:#   
+ata-update-26.dpatch:#   Driver should be using LIBATA_MAX_PRD not ATA_MAX_PRD,
+ata-update-26.dpatch:#   due to iommu layer splitting.
+ata-update-26.dpatch:# 
+ata-update-27.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-27.dpatch:#
+ata-update-27.dpatch:# ChangeSet
+ata-update-27.dpatch:#   2004/09/13 22:34:11-04:00 jgarzik at pobox.com 
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-27.dpatch:# drivers/scsi/ata_piix.c
+ata-update-27.dpatch:#   2004/09/13 22:34:03-04:00 jgarzik at pobox.com +12 -12
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-27.dpatch:# drivers/scsi/libata-core.c
+ata-update-27.dpatch:#   2004/09/13 22:34:03-04:00 jgarzik at pobox.com +71 -30
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-27.dpatch:# drivers/scsi/sata_nv.c
+ata-update-27.dpatch:#   2004/09/13 22:34:03-04:00 jgarzik at pobox.com +6 -6
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-27.dpatch:# drivers/scsi/sata_promise.c
+ata-update-27.dpatch:#   2004/09/13 22:34:03-04:00 jgarzik at pobox.com +4 -4
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-27.dpatch:# drivers/scsi/sata_sil.c
+ata-update-27.dpatch:#   2004/09/13 22:34:03-04:00 jgarzik at pobox.com +6 -6
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-27.dpatch:# drivers/scsi/sata_sis.c
+ata-update-27.dpatch:#   2004/09/13 22:34:03-04:00 jgarzik at pobox.com +6 -6
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-27.dpatch:# drivers/scsi/sata_svw.c
+ata-update-27.dpatch:#   2004/09/13 22:34:03-04:00 jgarzik at pobox.com +3 -3
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-27.dpatch:# drivers/scsi/sata_sx4.c
+ata-update-27.dpatch:#   2004/09/13 22:34:03-04:00 jgarzik at pobox.com +4 -4
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-27.dpatch:# drivers/scsi/sata_via.c
+ata-update-27.dpatch:#   2004/09/13 22:34:03-04:00 jgarzik at pobox.com +6 -6
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-27.dpatch:# drivers/scsi/sata_vsc.c
+ata-update-27.dpatch:#   2004/09/13 22:34:03-04:00 jgarzik at pobox.com +4 -4
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-27.dpatch:# include/linux/libata.h
+ata-update-27.dpatch:#   2004/09/13 22:34:03-04:00 jgarzik at pobox.com +6 -12
+ata-update-27.dpatch:#   [libata] remove distinction between MMIO/PIO helper functions
+ata-update-27.dpatch:#   
+ata-update-27.dpatch:#   Prepare for use of new generic iomap API.
+ata-update-27.dpatch:# 
+ata-update-28.dpatch:# backported to Debian's 2.6.8 by dann frazier <dannf at hp.com>
+ata-update-28.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-28.dpatch:#
+ata-update-28.dpatch:# ChangeSet
+ata-update-28.dpatch:#   2004/09/13 23:31:50-04:00 jgarzik at pobox.com 
+ata-update-28.dpatch:#   [libata] consolidate legacy/native mode init code into helpers
+ata-update-28.dpatch:#   
+ata-update-28.dpatch:#   Eliminates duplicate code in sata_nv, sata_sis, and sata_via.
+ata-update-28.dpatch:# 
+ata-update-28.dpatch:# drivers/scsi/libata-core.c
+ata-update-28.dpatch:#   2004/09/13 23:31:43-04:00 jgarzik at pobox.com +104 -77
+ata-update-28.dpatch:#   [libata] consolidate legacy/native mode init code into helpers
+ata-update-28.dpatch:#   
+ata-update-28.dpatch:#   Eliminates duplicate code in sata_nv, sata_sis, and sata_via.
+ata-update-28.dpatch:# 
+ata-update-28.dpatch:# drivers/scsi/sata_nv.c
+ata-update-28.dpatch:#   2004/09/13 23:31:43-04:00 jgarzik at pobox.com +15 -35
+ata-update-28.dpatch:#   [libata] consolidate legacy/native mode init code into helpers
+ata-update-28.dpatch:#   
+ata-update-28.dpatch:#   Eliminates duplicate code in sata_nv, sata_sis, and sata_via.
+ata-update-28.dpatch:# 
+ata-update-28.dpatch:# drivers/scsi/sata_sis.c
+ata-update-28.dpatch:#   2004/09/13 23:31:43-04:00 jgarzik at pobox.com +15 -31
+ata-update-28.dpatch:#   [libata] consolidate legacy/native mode init code into helpers
+ata-update-28.dpatch:#   
+ata-update-28.dpatch:#   Eliminates duplicate code in sata_nv, sata_sis, and sata_via.
+ata-update-28.dpatch:# 
+ata-update-28.dpatch:# drivers/scsi/sata_via.c
+ata-update-28.dpatch:#   2004/09/13 23:31:43-04:00 jgarzik at pobox.com +13 -28
+ata-update-28.dpatch:#   [libata] consolidate legacy/native mode init code into helpers
+ata-update-28.dpatch:#   
+ata-update-28.dpatch:#   Eliminates duplicate code in sata_nv, sata_sis, and sata_via.
+ata-update-28.dpatch:# 
+ata-update-28.dpatch:# include/linux/libata.h
+ata-update-28.dpatch:#   2004/09/13 23:31:43-04:00 jgarzik at pobox.com +4 -0
+ata-update-28.dpatch:#   [libata] consolidate legacy/native mode init code into helpers
+ata-update-28.dpatch:#   
+ata-update-28.dpatch:#   Eliminates duplicate code in sata_nv, sata_sis, and sata_via.
+ata-update-28.dpatch:# 
+ata-update-29.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-29.dpatch:#
+ata-update-29.dpatch:# ChangeSet
+ata-update-29.dpatch:#   2004/09/14 22:23:54-04:00 jgarzik at pobox.com 
+ata-update-29.dpatch:#   [libata] minor comment updates, preparing for iomap merge
+ata-update-29.dpatch:# 
+ata-update-29.dpatch:# drivers/scsi/libata-core.c
+ata-update-29.dpatch:#   2004/09/14 22:23:47-04:00 jgarzik at pobox.com +13 -13
+ata-update-29.dpatch:#   [libata] minor comment updates, preparing for iomap merge
+ata-update-29.dpatch:# 
+ata-update-29.dpatch:# drivers/scsi/sata_nv.c
+ata-update-29.dpatch:#   2004/09/14 22:23:47-04:00 jgarzik at pobox.com +0 -2
+ata-update-29.dpatch:#   [libata] minor comment updates, preparing for iomap merge
+ata-update-29.dpatch:# 
+ata-update-30.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-30.dpatch:#
+ata-update-30.dpatch:# ChangeSet
+ata-update-30.dpatch:#   2004/09/14 22:25:41-04:00 ananth at broadcom.com 
+ata-update-30.dpatch:#   [libata sata_svw] race condition fix, new device support
+ata-update-30.dpatch:#   
+ata-update-30.dpatch:#   * address race condition WRT order of DMA-start and ATA command issue
+ata-update-30.dpatch:#     (see code comment for more details)
+ata-update-30.dpatch:#   
+ata-update-30.dpatch:#   * Add support for Frodo 4/8
+ata-update-30.dpatch:# 
+ata-update-30.dpatch:# drivers/scsi/sata_svw.c
+ata-update-30.dpatch:#   2004/09/14 22:25:34-04:00 ananth at broadcom.com +70 -2
+ata-update-30.dpatch:#   [libata sata_svw] race condition fix, new device support
+ata-update-30.dpatch:#   
+ata-update-30.dpatch:#   * address race condition WRT order of DMA-start and ATA command issue
+ata-update-30.dpatch:#     (see code comment for more details)
+ata-update-30.dpatch:#   
+ata-update-30.dpatch:#   * Add support for Frodo 4/8
+ata-update-30.dpatch:# 
+ata-update-31.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-31.dpatch:#
+ata-update-31.dpatch:# ChangeSet
+ata-update-31.dpatch:#   2004/09/16 02:45:22-04:00 jgarzik at pobox.com 
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a variant that does not call
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-31.dpatch:# drivers/scsi/ata_piix.c
+ata-update-31.dpatch:#   2004/09/16 02:45:15-04:00 jgarzik at pobox.com +2 -0
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a variant that does not call
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-31.dpatch:# drivers/scsi/libata-core.c
+ata-update-31.dpatch:#   2004/09/16 02:45:15-04:00 jgarzik at pobox.com +41 -21
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a variant that does not call
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-31.dpatch:# drivers/scsi/sata_nv.c
+ata-update-31.dpatch:#   2004/09/16 02:45:15-04:00 jgarzik at pobox.com +1 -0
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a variant that does not call
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-31.dpatch:# drivers/scsi/sata_promise.c
+ata-update-31.dpatch:#   2004/09/16 02:45:15-04:00 jgarzik at pobox.com +1 -0
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a variant that does not call
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-31.dpatch:# drivers/scsi/sata_sil.c
+ata-update-31.dpatch:#   2004/09/16 02:45:15-04:00 jgarzik at pobox.com +1 -0
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a variant that does not call
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-31.dpatch:# drivers/scsi/sata_sis.c
+ata-update-31.dpatch:#   2004/09/16 02:45:15-04:00 jgarzik at pobox.com +1 -0
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a variant that does not call
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-31.dpatch:# drivers/scsi/sata_svw.c
+ata-update-31.dpatch:#   2004/09/16 02:45:15-04:00 jgarzik at pobox.com +1 -0
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a variant that does not call
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-31.dpatch:# drivers/scsi/sata_sx4.c
+ata-update-31.dpatch:#   2004/09/16 02:45:15-04:00 jgarzik at pobox.com +2 -1
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a variant that does not call
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-31.dpatch:# drivers/scsi/sata_via.c
+ata-update-31.dpatch:#   2004/09/16 02:45:15-04:00 jgarzik at pobox.com +1 -0
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a diff -Naru a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-31.dpatch:# drivers/scsi/sata_vsc.c
+ata-update-31.dpatch:#   2004/09/16 02:45:15-04:00 jgarzik at pobox.com +1 -0
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a variant that does not call
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-31.dpatch:# include/linux/libata.h
+ata-update-31.dpatch:#   2004/09/16 02:45:15-04:00 jgarzik at pobox.com +5 -0
+ata-update-31.dpatch:#   [libata] add hook, and export functions needed for sata2 drivers
+ata-update-31.dpatch:#   
+ata-update-31.dpatch:#   * add dev_select hook, and default/noop implementations
+ata-update-31.dpatch:#   * export ata_dev_classify
+ata-update-31.dpatch:#   * fix a couple bugs that cropped up when building with
+ata-update-31.dpatch:#     ATA_VERBOSE_DEBUG
+ata-update-31.dpatch:#   * export __sata_phy_reset, a variant that does not call
+ata-update-31.dpatch:#     ata_bus_reset
+ata-update-31.dpatch:# 
+ata-update-32.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-32.dpatch:#
+ata-update-32.dpatch:# ChangeSet
+ata-update-32.dpatch:#   2004/09/30 19:05:59-04:00 jgarzik at pobox.com 
+ata-update-32.dpatch:#   [libata] add sata_uli driver for ULi (formerly ALi) SATA
+ata-update-32.dpatch:#   
+ata-update-32.dpatch:#   Contributed by Peer Chen <peer_chen at ali.com.tw>, updated to
+ata-update-32.dpatch:#   latest libata by me.
+ata-update-32.dpatch:# 
+ata-update-32.dpatch:# drivers/scsi/Kconfig
+ata-update-32.dpatch:#   2004/09/30 19:05:51-04:00 jgarzik at pobox.com +8 -0
+ata-update-32.dpatch:#   [libata] add sata_uli driver for ULi (formerly ALi) SATA
+ata-update-32.dpatch:#   
+ata-update-32.dpatch:#   Contributed by Peer Chen <peer_chen at ali.com.tw>, updated to
+ata-update-32.dpatch:#   latest libata by me.
+ata-update-32.dpatch:# 
+ata-update-32.dpatch:# drivers/scsi/Makefile
+ata-update-32.dpatch:#   2004/09/30 19:05:51-04:00 jgarzik at pobox.com +1 -0
+ata-update-32.dpatch:#   [libata] add sata_uli driver for ULi (formerly ALi) SATA
+ata-update-32.dpatch:#   
+ata-update-32.dpatch:#   Contributed by Peer Chen <peer_chen at ali.com.tw>, updated to
+ata-update-32.dpatch:#   latest libata by me.
+ata-update-32.dpatch:# 
+ata-update-32.dpatch:# drivers/scsi/sata_uli.c
+ata-update-32.dpatch:#   2004/09/30 18:40:29-04:00 jgarzik at pobox.com +0 -0
+ata-update-32.dpatch:#   BitKeeper file /spare/repo/libata-2.6/drivers/scsi/sata_uli.c
+ata-update-32.dpatch:# 
+ata-update-32.dpatch:# drivers/scsi/sata_uli.c
+ata-update-32.dpatch:#   2004/09/30 18:40:29-04:00 jgarzik at pobox.com +284 -0
+ata-update-32.dpatch:# 
+ata-update-32.dpatch:# drivers/scsi/sata_uli.c
+ata-update-32.dpatch:#   2004/09/30 19:05:51-04:00 jgarzik at pobox.com +41 -44
+ata-update-32.dpatch:#   [libata] add sata_uli driver for ULi (formerly ALi) SATA
+ata-update-32.dpatch:#   
+ata-update-32.dpatch:#   Contributed by Peer Chen <peer_chen at ali.com.tw>, updated to
+ata-update-32.dpatch:#   latest libata by me.
+ata-update-32.dpatch:# 
+ata-update-33.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-33.dpatch:#
+ata-update-33.dpatch:# ChangeSet
+ata-update-33.dpatch:#   2004/09/30 22:11:06-04:00 jgarzik at pobox.com 
+ata-update-33.dpatch:#   [libata sata_uli] add dev_select hook
+ata-update-33.dpatch:# 
+ata-update-33.dpatch:# drivers/scsi/sata_uli.c
+ata-update-33.dpatch:#   2004/09/30 22:10:59-04:00 jgarzik at pobox.com +1 -0
+ata-update-33.dpatch:#   [libata sata_uli] add dev_select hook
+ata-update-33.dpatch:# 
+ata-update-34.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-34.dpatch:#
+ata-update-34.dpatch:# ChangeSet
+ata-update-34.dpatch:#   2004/09/30 23:37:25-04:00 romieu at fr.zoreil.com 
+ata-update-34.dpatch:#   [PATCH] sata_nv: enable hotplug event on successfull init only
+ata-update-34.dpatch:#   
+ata-update-34.dpatch:#   Wait for successfull completion of nv_init_one() before hotplug events
+ata-update-34.dpatch:#   are enabled.
+ata-update-34.dpatch:#   
+ata-update-34.dpatch:#   Signed-off-by: Francois Romieu <romieu at fr.zoreil.com>
+ata-update-34.dpatch:# 
+ata-update-34.dpatch:# drivers/scsi/sata_nv.c
+ata-update-34.dpatch:#   2004/09/29 16:16:21-04:00 romieu at fr.zoreil.com +4 -4
+ata-update-34.dpatch:#   sata_nv: enable hotplug event on successfull init only
+ata-update-34.dpatch:# 
+ata-update-35.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-35.dpatch:#
+ata-update-35.dpatch:# ChangeSet
+ata-update-35.dpatch:#   2004/09/30 23:40:35-04:00 romieu at fr.zoreil.com 
+ata-update-35.dpatch:#   [PATCH] sata_nv: wrong failure path and leak
+ata-update-35.dpatch:#   
+ata-update-35.dpatch:#   - wrong branching: the driver does not want to iounmap() an address that it
+ata-update-35.dpatch:#     has just failed to set;
+ata-update-35.dpatch:#   - return a sensible error status code instead of a success code;
+ata-update-35.dpatch:#   - leak plugged: host was never freed if a late error heppened.
+ata-update-35.dpatch:#   
+ata-update-35.dpatch:#   Signed-off-by: Francois Romieu <romieu at fr.zoreil.com>
+ata-update-35.dpatch:# 
+ata-update-35.dpatch:# drivers/scsi/sata_nv.c
+ata-update-35.dpatch:#   2004/09/29 16:16:15-04:00 romieu at fr.zoreil.com +6 -3
+ata-update-35.dpatch:#   sata_nv: wrong failure path and leak
+ata-update-35.dpatch:# 
+ata-update-36.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-36.dpatch:#
+ata-update-36.dpatch:# ChangeSet
+ata-update-36.dpatch:#   2004/09/30 23:53:02-04:00 romieu at fr.zoreil.com 
+ata-update-36.dpatch:#   [PATCH] sata_nv: housekeeping for goto labels
+ata-update-36.dpatch:#   
+ata-update-36.dpatch:#   - each label used in a goto contains a part of the operation that must
+ata-update-36.dpatch:#     be issued. This way both the no-error and the error paths can be checked
+ata-update-36.dpatch:#     separately;
+ata-update-36.dpatch:#   - probe_ent does not need to be NULL-initialized.
+ata-update-36.dpatch:#   
+ata-update-36.dpatch:#   Signed-off-by: Francois Romieu <romieu at fr.zoreil.com>
+ata-update-36.dpatch:# 
+ata-update-36.dpatch:# drivers/scsi/sata_nv.c
+ata-update-36.dpatch:#   2004/09/29 16:16:02-04:00 romieu at fr.zoreil.com +9 -12
+ata-update-36.dpatch:#   sata_nv: housekeeping for goto labels
+ata-update-36.dpatch:# 
+ata-update-37.dpatch:# Backported to Debian's 2.6.8 by dann frazier <dannf at hp.com>
+ata-update-37.dpatch:# Most of this changeset is already included via ata_piix-combinde-mode-fix-2.dpatch,
+ata-update-37.dpatch:# But it looks like this hunk got dropped
+ata-update-37.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-37.dpatch:#
+ata-update-37.dpatch:# ChangeSet
+ata-update-37.dpatch:#   2004/10/11 20:11:55-04:00 bzolnier at elka.pw.edu.pl 
+ata-update-37.dpatch:#   [PATCH] libata: PCI IDE legacy mode fix
+ata-update-37.dpatch:#   
+ata-update-37.dpatch:#   In PCI IDE legacy mode ap->port_no is incorrectly set to zero for
+ata-update-37.dpatch:#   the second port.  Fix it by adding ->hard_port_no to struct ata_probe_ent
+ata-update-37.dpatch:#   and struct ata_port (per Jeff's suggestion) and teaching ata_piix.c
+ata-update-37.dpatch:#   to use it instead of ->port_no.
+ata-update-37.dpatch:#   
+ata-update-37.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-37.dpatch:# 
+ata-update-37.dpatch:# drivers/scsi/ata_piix.c
+ata-update-37.dpatch:#   2004/10/11 15:52:22-04:00 bzolnier at elka.pw.edu.pl +10 -10
+ata-update-37.dpatch:#   PCI IDE legacy mode fix
+ata-update-37.dpatch:# 
+ata-update-37.dpatch:# drivers/scsi/libata-core.c
+ata-update-37.dpatch:#   2004/10/11 15:52:22-04:00 bzolnier at elka.pw.edu.pl +8 -0
+ata-update-37.dpatch:#   PCI IDE legacy mode fix
+ata-update-37.dpatch:# 
+ata-update-37.dpatch:# include/linux/libata.h
+ata-update-37.dpatch:#   2004/10/11 15:52:22-04:00 bzolnier at elka.pw.edu.pl +2 -0
+ata-update-37.dpatch:#   PCI IDE legacy mode fix
+ata-update-37.dpatch:# 
+ata-update-38.dpatch:# Backported to Debian's 2.6.8 by dann frazier <dannf at hp.com>
+ata-update-38.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-38.dpatch:#
+ata-update-38.dpatch:# ChangeSet
+ata-update-38.dpatch:#   2004/10/15 00:10:41-04:00 jgarzik at pobox.com 
+ata-update-38.dpatch:#   [libata] add AHCI driver
+ata-update-38.dpatch:# 
+ata-update-38.dpatch:# drivers/scsi/Kconfig
+ata-update-38.dpatch:#   2004/10/15 00:10:33-04:00 jgarzik at pobox.com +8 -0
+ata-update-38.dpatch:#   [libata] add AHCI driver
+ata-update-38.dpatch:# 
+ata-update-38.dpatch:# drivers/scsi/Makefile
+ata-update-38.dpatch:#   2004/10/15 00:10:33-04:00 jgarzik at pobox.com +1 -0
+ata-update-38.dpatch:#   [libata] add AHCI driver
+ata-update-38.dpatch:# 
+ata-update-38.dpatch:# drivers/scsi/ahci.c
+ata-update-38.dpatch:#   2004/10/15 00:10:33-04:00 jgarzik at pobox.com +0 -0
+ata-update-38.dpatch:#   BitKeeper file /spare/repo/libata-dev/ahci/drivers/scsi/ahci.c
+ata-update-38.dpatch:# 
+ata-update-38.dpatch:# drivers/scsi/ahci.c
+ata-update-38.dpatch:#   2004/10/15 00:10:33-04:00 jgarzik at pobox.com +973 -0
+ata-update-38.dpatch:# 
+ata-update-39.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-39.dpatch:#
+ata-update-39.dpatch:# ChangeSet
+ata-update-39.dpatch:#   2004/10/15 00:11:44-04:00 jgarzik at pobox.com 
+ata-update-39.dpatch:#   [libata ahci] fix several bugs
+ata-update-39.dpatch:#     
+ata-update-39.dpatch:#   * PCI IDs from test version didn't make it into mainline... doh
+ata-update-39.dpatch:#   * do all command setup in ->qc_prep
+ata-update-39.dpatch:#   * phy_reset routine that does signature check
+ata-update-39.dpatch:#   * check SATA phy for errors
+ata-update-39.dpatch:#   * reset hardware from scratch, in case card BIOS didn't run
+ata-update-39.dpatch:#   * implement staggered spinup by default
+ata-update-39.dpatch:#   * adding additional debugging output
+ata-update-39.dpatch:# 
+ata-update-39.dpatch:# drivers/scsi/ahci.c
+ata-update-39.dpatch:#   2004/10/15 00:11:36-04:00 jgarzik at pobox.com +109 -41
+ata-update-39.dpatch:#   [libata ahci] fix several bugs
+ata-update-39.dpatch:#     
+ata-update-39.dpatch:#   * PCI IDs from test version didn't make it into mainline... doh
+ata-update-39.dpatch:#   * do all command setup in ->qc_prep
+ata-update-39.dpatch:#   * phy_reset routine that does signature check
+ata-update-39.dpatch:#   * check SATA phy for errors
+ata-update-39.dpatch:#   * reset hardware from scratch, in case card BIOS didn't run
+ata-update-39.dpatch:#   * implement staggered spinup by default
+ata-update-39.dpatch:#   * adding additional debugging output
+ata-update-39.dpatch:# 
+ata-update-40.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-40.dpatch:#
+ata-update-40.dpatch:# ChangeSet
+ata-update-40.dpatch:#   2004/10/15 00:12:20-04:00 jgarzik at pobox.com 
+ata-update-40.dpatch:#   [libata ahci] more updates
+ata-update-40.dpatch:#   
+ata-update-40.dpatch:#   * allocate DMA areas in better order
+ata-update-40.dpatch:#   * remove unneeded hooks
+ata-update-40.dpatch:# 
+ata-update-40.dpatch:# drivers/scsi/ahci.c
+ata-update-40.dpatch:#   2004/10/15 00:12:12-04:00 jgarzik at pobox.com +28 -46
+ata-update-40.dpatch:#   [libata ahci] more updates
+ata-update-40.dpatch:#   
+ata-update-40.dpatch:#   * allocate DMA areas in better order
+ata-update-40.dpatch:#   * remove unneeded hooks
+ata-update-40.dpatch:# 
+ata-update-41.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-41.dpatch:#
+ata-update-41.dpatch:# ChangeSet
+ata-update-41.dpatch:#   2004/10/15 00:32:32-04:00 jeremy at sgi.com 
+ata-update-41.dpatch:#   [PATCH] per-port LED control for sata_vsc
+ata-update-41.dpatch:#   
+ata-update-41.dpatch:#   signed-off-by: Jeremy Higdon <jeremy at sgi.com>
+ata-update-41.dpatch:# 
+ata-update-41.dpatch:# drivers/scsi/sata_vsc.c
+ata-update-41.dpatch:#   2004/10/15 00:32:24-04:00 jeremy at sgi.com +8 -0
+ata-update-41.dpatch:#   [PATCH] per-port LED control for sata_vsc
+ata-update-41.dpatch:#   
+ata-update-41.dpatch:#   signed-off-by: Jeremy Higdon <jeremy at sgi.com>
+ata-update-41.dpatch:# 
+ata-update-42.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-42.dpatch:#
+ata-update-42.dpatch:# ChangeSet
+ata-update-42.dpatch:#   2004/10/15 01:11:22-04:00 lsml at rtr.ca 
+ata-update-42.dpatch:#   [PATCH] Export ata_scsi_simulate() for use by non-libata drivers
+ata-update-42.dpatch:#   
+ata-update-42.dpatch:#   This patch modifies libata-scsi for easier sharing of
+ata-update-42.dpatch:#   the various ata_id_* functions and the ata_scsi_simulate()
+ata-update-42.dpatch:#   function with non-libata drivers.
+ata-update-42.dpatch:#   
+ata-update-42.dpatch:#   Signed-off-by: Mark Lord <mlord at pobox.com>
+ata-update-42.dpatch:#   Signed-off-by: Jeff Garzik <jgarzik at pobox.com>
+ata-update-42.dpatch:# 
+ata-update-42.dpatch:# drivers/scsi/libata-core.c
+ata-update-42.dpatch:#   2004/10/14 14:33:54-04:00 lsml at rtr.ca +10 -9
+ata-update-42.dpatch:#   Export ata_scsi_simulate() for use by non-libata drivers
+ata-update-42.dpatch:# 
+ata-update-42.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-42.dpatch:#   2004/10/14 14:36:45-04:00 lsml at rtr.ca +31 -35
+ata-update-42.dpatch:#   Export ata_scsi_simulate() for use by non-libata drivers
+ata-update-42.dpatch:# 
+ata-update-42.dpatch:# drivers/scsi/libata.h
+ata-update-42.dpatch:#   2004/10/14 11:48:35-04:00 lsml at rtr.ca +2 -3
+ata-update-42.dpatch:#   Export ata_scsi_simulate() for use by non-libata drivers
+ata-update-42.dpatch:# 
+ata-update-42.dpatch:# drivers/scsi/sata_sil.c
+ata-update-42.dpatch:#   2004/10/14 12:05:23-04:00 lsml at rtr.ca +1 -1
+ata-update-42.dpatch:#   Export ata_scsi_simulate() for use by non-libata drivers
+ata-update-42.dpatch:# 
+ata-update-42.dpatch:# include/linux/ata.h
+ata-update-42.dpatch:#   2004/10/14 11:51:26-04:00 lsml at rtr.ca +18 -18
+ata-update-42.dpatch:#   Export ata_scsi_simulate() for use by non-libata drivers
+ata-update-42.dpatch:# 
+ata-update-42.dpatch:# include/linux/libata.h
+ata-update-42.dpatch:#   2004/10/14 14:35:41-04:00 lsml at rtr.ca +7 -5
+ata-update-42.dpatch:#   Export ata_scsi_simulate() for use by non-libata drivers
+ata-update-42.dpatch:# 
+ata-update-43.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-43.dpatch:#
+ata-update-43.dpatch:# ChangeSet
+ata-update-43.dpatch:#   2004/10/15 02:10:29-04:00 bzolnier at gmail.com 
+ata-update-43.dpatch:#   [libata piix] Fix PATA UDMA masks
+ata-update-43.dpatch:#   
+ata-update-43.dpatch:#   piix_pata_cbl_detect() handles cable detection just fine.
+ata-update-43.dpatch:#   
+ata-update-43.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-43.dpatch:# 
+ata-update-43.dpatch:# drivers/scsi/ata_piix.c
+ata-update-43.dpatch:#   2004/10/15 02:10:21-04:00 bzolnier at gmail.com +3 -3
+ata-update-43.dpatch:#   [libata piix] Fix PATA UDMA masks
+ata-update-43.dpatch:#   
+ata-update-43.dpatch:#   piix_pata_cbl_detect() handles cable detection just fine.
+ata-update-43.dpatch:#   
+ata-update-43.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-43.dpatch:# 
+ata-update-44.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-44.dpatch:#
+ata-update-44.dpatch:# ChangeSet
+ata-update-44.dpatch:#   2004/10/15 19:57:56-04:00 bzolnier at gmail.com 
+ata-update-44.dpatch:#   [PATCH] REQUEST_SENSE support for ATAPI
+ata-update-44.dpatch:#   
+ata-update-44.dpatch:#   It is quite different from your patch:
+ata-update-44.dpatch:#   * uses ata_qc_issue()
+ata-update-44.dpatch:#   * supports both DMA and PIO
+ata-update-44.dpatch:#   * ->sense_buffer[] mangling dropped for now
+ata-update-44.dpatch:#   
+ata-update-44.dpatch:#   Now libata works with ATAPI devices (yeah!)...
+ata-update-44.dpatch:#   ...unless PIO is used, then it fails in mysterious way.
+ata-update-44.dpatch:#   
+ata-update-44.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-44.dpatch:# 
+ata-update-44.dpatch:# drivers/scsi/libata-core.c
+ata-update-44.dpatch:#   2004/10/15 18:52:33-04:00 bzolnier at gmail.com +100 -20
+ata-update-44.dpatch:#   REQUEST_SENSE support for ATAPI
+ata-update-44.dpatch:# 
+ata-update-44.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-44.dpatch:#   2004/10/15 18:52:33-04:00 bzolnier at gmail.com +8 -2
+ata-update-44.dpatch:#   REQUEST_SENSE support for ATAPI
+ata-update-44.dpatch:# 
+ata-update-45.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-45.dpatch:#
+ata-update-45.dpatch:# ChangeSet
+ata-update-45.dpatch:#   2004/10/15 19:59:34-04:00 bzolnier at gmail.com 
+ata-update-45.dpatch:#   [libata] arbitrary size ATAPI PIO support
+ata-update-45.dpatch:#   
+ata-update-45.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-45.dpatch:# 
+ata-update-45.dpatch:# drivers/scsi/libata-core.c
+ata-update-45.dpatch:#   2004/10/15 19:59:26-04:00 bzolnier at gmail.com +44 -13
+ata-update-45.dpatch:#   [libata] arbitrary size ATAPI PIO support
+ata-update-45.dpatch:#   
+ata-update-45.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-45.dpatch:# 
+ata-update-45.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-45.dpatch:#   2004/10/15 19:59:26-04:00 bzolnier at gmail.com +2 -0
+ata-update-45.dpatch:#   [libata] arbitrary size ATAPI PIO support
+ata-update-45.dpatch:#   
+ata-update-45.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-45.dpatch:# 
+ata-update-45.dpatch:# include/linux/libata.h
+ata-update-45.dpatch:#   2004/10/15 19:59:26-04:00 bzolnier at gmail.com +4 -0
+ata-update-45.dpatch:#   [libata] arbitrary size ATAPI PIO support
+ata-update-45.dpatch:#   
+ata-update-45.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-45.dpatch:# 
+ata-update-46.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-46.dpatch:#
+ata-update-46.dpatch:# ChangeSet
+ata-update-46.dpatch:#   2004/10/18 17:49:16-04:00 bzolnier at gmail.com 
+ata-update-46.dpatch:#   [PATCH] arbitrary size ATAPI PIO support bugfixes
+ata-update-46.dpatch:#   
+ata-update-46.dpatch:#   * sg was incorrectly used instead of qc->sg in __atapi_pio_bytes()
+ata-update-46.dpatch:#   * due to obvious typo qc->curbytes wasn't zeroed in ata_qc_new_init()
+ata-update-46.dpatch:#   
+ata-update-46.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-46.dpatch:# 
+ata-update-46.dpatch:# drivers/scsi/libata-core.c
+ata-update-46.dpatch:#   2004/10/18 16:31:59-04:00 bzolnier at gmail.com +2 -2
+ata-update-46.dpatch:#   arbitrary size ATAPI PIO support bugfixes
+ata-update-46.dpatch:# 
+ata-update-47.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-47.dpatch:#
+ata-update-47.dpatch:# ChangeSet
+ata-update-47.dpatch:#   2004/10/18 17:49:29-04:00 bzolnier at gmail.com 
+ata-update-47.dpatch:#   [PATCH] make ATAPI PIO work
+ata-update-47.dpatch:#   
+ata-update-47.dpatch:#   If "BSY=0, DRQ=0" condition happens on ATAPI just
+ata-update-47.dpatch:#   complete the command as this condition happens for:
+ata-update-47.dpatch:#   * the end of the PIO transfer (ie. REQUEST_SENSE
+ata-update-47.dpatch:#     seems to return only 18 of 96 requested bytes)
+ata-update-47.dpatch:#   * unsupported ATAPI commands (ie. REPORT_LUNS)
+ata-update-47.dpatch:#   
+ata-update-47.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-47.dpatch:# 
+ata-update-47.dpatch:# drivers/scsi/libata-core.c
+ata-update-47.dpatch:#   2004/10/18 17:10:12-04:00 bzolnier at gmail.com +19 -8
+ata-update-47.dpatch:#   make ATAPI PIO work
+ata-update-47.dpatch:# 
+ata-update-48.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-48.dpatch:#
+ata-update-48.dpatch:# ChangeSet
+ata-update-48.dpatch:#   2004/10/20 04:27:39-04:00 akpm at osdl.org 
+ata-update-48.dpatch:#   [PATCH] sata_sil mod15 quirk with Seagate ST3120026AS
+ata-update-48.dpatch:#   
+ata-update-48.dpatch:#   From: <stuart at cybertherial.com>
+ata-update-48.dpatch:#   
+ata-update-48.dpatch:#   Hardware Environment: AMD64, sil3512 controller on m/b.  Harddrive: Seagate
+ata-update-48.dpatch:#   120GB ST3120026AS
+ata-update-48.dpatch:#   
+ata-update-48.dpatch:#   Problem Description: Drive would lock when writing large files, eg video
+ata-update-48.dpatch:#   from firewire, audio editing.  Checked dmesg, was obviously the sata drive.
+ata-update-48.dpatch:#   
+ata-update-48.dpatch:#   Have added the drive to the blacklist in sata_sil.c and the problem seems
+ata-update-48.dpatch:#   to have disappeared.
+ata-update-48.dpatch:#   
+ata-update-48.dpatch:#   Is there a good test to verify that the mod15 bug is really the problem?
+ata-update-48.dpatch:#   
+ata-update-48.dpatch:#   Signed-off-by: Andrew Morton <akpm at osdl.org>
+ata-update-48.dpatch:# 
+ata-update-48.dpatch:# drivers/scsi/sata_sil.c
+ata-update-48.dpatch:#   2004/10/07 10:01:18-04:00 akpm at osdl.org +1 -0
+ata-update-48.dpatch:#   sata_sil mod15 quirk with Seagate ST3120026AS
+ata-update-48.dpatch:# 
+ata-update-49.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-49.dpatch:#
+ata-update-49.dpatch:# ChangeSet
+ata-update-49.dpatch:#   2004/10/27 22:59:13-04:00 jgarzik at pobox.com 
+ata-update-49.dpatch:#   [libata] cosmetic libata.h changes to make merging with 2.4 easier
+ata-update-49.dpatch:# 
+ata-update-49.dpatch:# include/linux/libata.h
+ata-update-49.dpatch:#   2004/10/27 22:59:07-04:00 jgarzik at pobox.com +2 -3
+ata-update-49.dpatch:#   [libata] cosmetic libata.h changes to make merging with 2.4 easier
+ata-update-49.dpatch:# 
+ata-update-50.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-50.dpatch:#
+ata-update-50.dpatch:# ChangeSet
+ata-update-50.dpatch:#   2004/10/30 08:46:14-04:00 nacc at us.ibm.com 
+ata-update-50.dpatch:#   [PATCH] scsi/ahci: replace schedule_timeout() with msleep()/ssleep()
+ata-update-50.dpatch:#   
+ata-update-50.dpatch:#   Description: Uses msleep() / ssleep() [as appropriate] instead of
+ata-update-50.dpatch:#   schedule_timeout() to guarantee the task delays as expected.
+ata-update-50.dpatch:#   
+ata-update-50.dpatch:#   Signed-off-by: Nishanth Aravamudan <nacc at us.ibm.com>
+ata-update-50.dpatch:#   Signed-off-by: Jeff Garzik <jgarzik at pobox.com>
+ata-update-50.dpatch:# 
+ata-update-50.dpatch:# drivers/scsi/ahci.c
+ata-update-50.dpatch:#   2004/10/22 18:20:02-04:00 nacc at us.ibm.com +3 -6
+ata-update-50.dpatch:#   scsi/ahci: replace schedule_timeout() with msleep()/ssleep()
+ata-update-50.dpatch:# 
+ata-update-51.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-51.dpatch:#
+ata-update-51.dpatch:# ChangeSet
+ata-update-51.dpatch:#   2004/10/30 11:34:30-04:00 tobias.lorenz at gmx.net 
+ata-update-51.dpatch:#   [libata sata_promise] s/sata/ata/
+ata-update-51.dpatch:#   
+ata-update-51.dpatch:#   100% cosmetic:  rename various symbols with 'sata' in them to 'ata',
+ata-update-51.dpatch:#   in preparation for addition of support for a PATA controller.
+ata-update-51.dpatch:#   
+ata-update-51.dpatch:#   Signed-off-by: Tobias Lorenz <tobias.lorenz at gmx.net>
+ata-update-51.dpatch:#   Signed-off-by: Jeff Garzik <jgarzik at pobox.com>
+ata-update-51.dpatch:# 
+ata-update-51.dpatch:# drivers/scsi/sata_promise.c
+ata-update-51.dpatch:#   2004/10/30 11:34:24-04:00 tobias.lorenz at gmx.net +24 -24
+ata-update-51.dpatch:#   [libata sata_promise] s/sata/ata/
+ata-update-51.dpatch:#   
+ata-update-51.dpatch:#   100% cosmetic:  rename various symbols with 'sata' in them to 'ata',
+ata-update-51.dpatch:#   in preparation for addition of support for a PATA controller.
+ata-update-51.dpatch:#   
+ata-update-51.dpatch:#   Signed-off-by: Tobias Lorenz <tobias.lorenz at gmx.net>
+ata-update-51.dpatch:#   Signed-off-by: Jeff Garzik <jgarzik at pobox.com>
+ata-update-51.dpatch:# 
+ata-update-52.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-52.dpatch:#
+ata-update-52.dpatch:# ChangeSet
+ata-update-52.dpatch:#   2004/10/30 20:13:57-04:00 mmelchior at xs4all.nl 
+ata-update-52.dpatch:#   [libata ahci] fix rather serious (and/or embarassing) bugs
+ata-update-52.dpatch:#   
+ata-update-52.dpatch:#   - Add definition for SActive register
+ata-update-52.dpatch:#   - Add most interrupt sources to default interrupt mask
+ata-update-52.dpatch:#   - Write low 32 bits of FIS address to PxFB, where they belong
+ata-update-52.dpatch:#   - Set command active bit in PxSACT before setting command issue bit in PxCI
+ata-update-52.dpatch:#   - Announce Sub Class Code in driver info message [IDE, SATA or RAID]
+ata-update-52.dpatch:#   
+ata-update-52.dpatch:#   and additionally, from me [jgarzik]:
+ata-update-52.dpatch:#   - ignore ports-implemented bitmap for now; it's a write-only register
+ata-update-52.dpatch:#     that silly BIOSen initialize incorreclty
+ata-update-52.dpatch:#   
+ata-update-52.dpatch:#   Signed-off-by: Matthijs Melchior <mmelchior at xs4all.nl>
+ata-update-52.dpatch:#   Signed-off-by: Jeff Garzik <jgarzik at pobox.com>
+ata-update-52.dpatch:# 
+ata-update-52.dpatch:# drivers/scsi/ahci.c
+ata-update-52.dpatch:#   2004/10/30 20:13:51-04:00 mmelchior at xs4all.nl +29 -7
+ata-update-52.dpatch:#   [libata ahci] fix rather serious (and/or embarassing) bugs
+ata-update-52.dpatch:#   
+ata-update-52.dpatch:#   - Add definition for SActive register
+ata-update-52.dpatch:#   - Add most interrupt sources to default interrupt mask
+ata-update-52.dpatch:#   - Write low 32 bits of FIS address to PxFB, where they belong
+ata-update-52.dpatch:#   - Set command active bit in PxSACT before setting command issue bit in PxCI
+ata-update-52.dpatch:#   - Announce Sub Class Code in driver info message [IDE, SATA or RAID]
+ata-update-52.dpatch:#   
+ata-update-52.dpatch:#   and additionally, from me [jgarzik]:
+ata-update-52.dpatch:#   - ignore ports-implemented bitmap for now; it's a write-only register
+ata-update-52.dpatch:#     that silly BIOSen initialize incorreclty
+ata-update-52.dpatch:#   
+ata-update-52.dpatch:#   Signed-off-by: Matthijs Melchior <mmelchior at xs4all.nl>
+ata-update-52.dpatch:#   Signed-off-by: Jeff Garzik <jgarzik at pobox.com>
+ata-update-52.dpatch:# 
+ata-update-53.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-53.dpatch:#
+ata-update-53.dpatch:# ChangeSet
+ata-update-53.dpatch:#   2004/10/30 20:14:40-04:00 jgarzik at pobox.com 
+ata-update-53.dpatch:#   [libata ahci] bump version to 1.00
+ata-update-53.dpatch:# 
+ata-update-53.dpatch:# drivers/scsi/ahci.c
+ata-update-53.dpatch:#   2004/10/30 20:14:34-04:00 jgarzik at pobox.com +1 -1
+ata-update-53.dpatch:#   [libata ahci] bump version to 1.00
+ata-update-53.dpatch:# 
+ata-update-54.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-54.dpatch:#
+ata-update-54.dpatch:# ChangeSet
+ata-update-54.dpatch:#   2004/11/02 07:50:59-05:00 bzolnier at elka.pw.edu.pl 
+ata-update-54.dpatch:#   [PATCH] libata PIO bugfix
+ata-update-54.dpatch:#   
+ata-update-54.dpatch:#   Untested but based on working IDE fix.
+ata-update-54.dpatch:#   
+ata-update-54.dpatch:#   We need to kmap()/kunmap() the current page
+ata-update-54.dpatch:#   not the first page of the scatterlist segment.
+ata-update-54.dpatch:#   
+ata-update-54.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-54.dpatch:#   Signed-off-by: Jeff Garzik <jgarzik at pobox.com>
+ata-update-54.dpatch:# 
+ata-update-54.dpatch:# drivers/scsi/libata-core.c
+ata-update-54.dpatch:#   2004/10/30 17:51:12-04:00 bzolnier at elka.pw.edu.pl +25 -5
+ata-update-54.dpatch:#   PIO bugfix
+ata-update-54.dpatch:# 
+ata-update-55.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-55.dpatch:#
+ata-update-55.dpatch:# ChangeSet
+ata-update-55.dpatch:#   2004/11/05 22:14:55+01:00 bzolnier at trik.(none) 
+ata-update-55.dpatch:#   [ide] (partially) unify hdreg.h & ata.h
+ata-update-55.dpatch:#   
+ata-update-55.dpatch:#   Signed-off-by: Chris Wedgwood <cw at f00f.org>
+ata-update-55.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-55.dpatch:# 
+ata-update-55.dpatch:# include/linux/ata.h
+ata-update-55.dpatch:#   2004/11/02 20:32:44+01:00 bzolnier at trik.(none) +6 -2
+ata-update-55.dpatch:#   [ide] (partially) unify hdreg.h & ata.h
+ata-update-55.dpatch:# 
+ata-update-55.dpatch:# include/linux/hdreg.h
+ata-update-55.dpatch:#   2004/11/02 20:32:44+01:00 bzolnier at trik.(none) +2 -21
+ata-update-55.dpatch:#   [ide] (partially) unify hdreg.h & ata.h
+ata-update-55.dpatch:# 
+ata-update-56.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-56.dpatch:#
+ata-update-56.dpatch:# ChangeSet
+ata-update-56.dpatch:#   2004/11/06 13:39:18-05:00 mroos at linux.ee 
+ata-update-56.dpatch:#   [PATCH] ata.h undefined types in USB
+ata-update-56.dpatch:#   
+ata-update-56.dpatch:#   This is todays BK on a x86:
+ata-update-56.dpatch:#   
+ata-update-56.dpatch:#     CC [M]  drivers/usb/storage/freecom.o
+ata-update-56.dpatch:#   In file included from include/linux/hdreg.h:4,
+ata-update-56.dpatch:#                    from drivers/usb/storage/freecom.c:32:
+ata-update-56.dpatch:#   include/linux/ata.h:197: error: parse error before "u32"
+ata-update-56.dpatch:#   ...
+ata-update-56.dpatch:#   and so on for tens of lines.
+ata-update-56.dpatch:#   
+ata-update-56.dpatch:#   Signed-off-by: Jeff Garzik <jgarzik at pobox.com>
+ata-update-56.dpatch:# 
+ata-update-56.dpatch:# include/linux/ata.h
+ata-update-56.dpatch:#   2004/11/06 09:47:08-05:00 mroos at linux.ee +2 -0
+ata-update-56.dpatch:#   ata.h undefined types in USB
+ata-update-56.dpatch:# 
+ata-update-57.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-57.dpatch:#
+ata-update-57.dpatch:# ChangeSet
+ata-update-57.dpatch:#   2004/11/06 13:44:22-05:00 jgarzik at pobox.com 
+ata-update-57.dpatch:#   Remove silly comment from linux/ata.h.
+ata-update-57.dpatch:#   
+ata-update-57.dpatch:#   XFER_xxx is not necessarily "legacy IDE 'stuff'"
+ata-update-57.dpatch:# 
+ata-update-57.dpatch:# include/linux/ata.h
+ata-update-57.dpatch:#   2004/11/06 13:44:16-05:00 jgarzik at pobox.com +0 -2
+ata-update-57.dpatch:#   Remove silly comment from linux/ata.h.
+ata-update-57.dpatch:#   
+ata-update-57.dpatch:#   XFER_xxx is not necessarily "legacy IDE 'stuff'"
+ata-update-57.dpatch:# 
+ata-update-58.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-58.dpatch:#
+ata-update-58.dpatch:# ChangeSet
+ata-update-58.dpatch:#   2004/11/12 19:01:32-05:00 jgarzik at pobox.com 
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/ahci.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +8 -8
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/ata_piix.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +7 -6
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/libata-core.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +39 -31
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +1 -1
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/sata_nv.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +6 -4
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/sata_promise.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +5 -5
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/sata_sil.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +1 -1
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/sata_sis.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +4 -2
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/sata_svw.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +1 -1
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers indiff -Naru a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/sata_sx4.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +5 -5
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/sata_uli.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +4 -2
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# drivers/scsi/sata_vsc.c
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +1 -1
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-58.dpatch:# include/linux/libata.h
+ata-update-58.dpatch:#   2004/11/12 19:01:26-05:00 jgarzik at pobox.com +30 -14
+ata-update-58.dpatch:#   [libata] remove dependence on PCI
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   Most of this work was done by "Mat Loikkanen" <Mat.Loikkanen at synopsys.com>.
+ata-update-58.dpatch:#   
+ata-update-58.dpatch:#   * use struct device rather than struct pci_dev
+ata-update-58.dpatch:#   * use generic DMA routines (dma_xxx) and generic struct device
+ata-update-58.dpatch:#     routines (dev_xxx)
+ata-update-58.dpatch:#   * isolate PCI-specific helpers inside CONFIG_PCI
+ata-update-58.dpatch:# 
+ata-update-59.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-59.dpatch:#
+ata-update-59.dpatch:# ChangeSet
+ata-update-59.dpatch:#   2004/11/13 14:24:11-05:00 jgarzik at pobox.com 
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/Kconfig
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +7 -7
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/ata_piix.c
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +2 -1
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/libata-core.c
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +1 -0
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/libata.h
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +1 -1
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/sata_nv.c
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +2 -1
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/sata_promise.c
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +2 -1
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/sata_sil.c
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +2 -1
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/sata_sis.c
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +2 -1
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/sata_svw.c
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +2 -1
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/sata_sx4.c
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +2 -1
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/sata_uli.c
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +2 -1
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/sata_via.c
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +2 -1
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-59.dpatch:# drivers/scsi/sata_vsc.c
+ata-update-59.dpatch:#   2004/11/13 14:24:05-05:00 jgarzik at pobox.com +2 -1
+ata-update-59.dpatch:#   [libata] bump versions, add MODULE_VERSION() tags
+ata-update-59.dpatch:#   
+ata-update-59.dpatch:#   Also remove dep on CONFIG_EXPERIMENTAL for libata itself,
+ata-update-59.dpatch:#   and several libata drivers.
+ata-update-59.dpatch:# 
+ata-update-60.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-60.dpatch:#
+ata-update-60.dpatch:# ChangeSet
+ata-update-60.dpatch:#   2004/11/14 05:14:54-05:00 hch at lst.de 
+ata-update-60.dpatch:#   [PATCH] fix sata_svw compile
+ata-update-60.dpatch:#   
+ata-update-60.dpatch:#   Current BK doesn't compile with the G5 defconfig because the last
+ata-update-60.dpatch:#   libata updated missed to change sata_svw to the new conventions.
+ata-update-60.dpatch:#   
+ata-update-60.dpatch:#   Signed-off-by: Jeff Garzik <jgarzik at pobox.com>
+ata-update-60.dpatch:# 
+ata-update-60.dpatch:# drivers/scsi/sata_svw.c
+ata-update-60.dpatch:#   2004/11/14 04:52:21-05:00 hch at lst.de +1 -1
+ata-update-60.dpatch:#   fix sata_svw compile
+ata-update-60.dpatch:# 
+ata-update-61.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-61.dpatch:#
+ata-update-61.dpatch:# ChangeSet
+ata-update-61.dpatch:#   2004/11/15 00:17:15-05:00 jgarzik at pobox.com 
+ata-update-61.dpatch:#   [libata] fix DocBook bugs
+ata-update-61.dpatch:# 
+ata-update-61.dpatch:# drivers/scsi/libata-core.c
+ata-update-61.dpatch:#   2004/11/15 00:17:09-05:00 jgarzik at pobox.com +6 -4
+ata-update-61.dpatch:#   [libata] fix DocBook bugs
+ata-update-61.dpatch:# 
+ata-update-61.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-61.dpatch:#   2004/11/15 00:17:09-05:00 jgarzik at pobox.com +3 -1
+ata-update-61.dpatch:#   [libata] fix DocBook bugs
+ata-update-61.dpatch:# 
+ata-update-62.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-62.dpatch:#
+ata-update-62.dpatch:# ChangeSet
+ata-update-62.dpatch:#   2004/11/16 02:17:36-05:00 jgarzik at pobox.com 
+ata-update-62.dpatch:#   [libata sata_uli] add 5281 support, fix SATA phy setup for others
+ata-update-62.dpatch:#   
+ata-update-62.dpatch:#   Contributed by Peer Chen @ ULi and tested by a user.
+ata-update-62.dpatch:# 
+ata-update-62.dpatch:# drivers/scsi/sata_uli.c
+ata-update-62.dpatch:#   2004/11/16 02:17:30-05:00 jgarzik at pobox.com +23 -28
+ata-update-62.dpatch:#   [libata sata_uli] add 5281 support, fix SATA phy setup for others
+ata-update-62.dpatch:#   
+ata-update-62.dpatch:#   Contributed by Peer Chen @ ULi and tested by a user.
+ata-update-62.dpatch:# 
+ata-update-63.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-63.dpatch:#
+ata-update-63.dpatch:# ChangeSet
+ata-update-63.dpatch:#   2004/11/16 19:01:52-05:00 jgarzik at pobox.com 
+ata-update-63.dpatch:#   [libata ahci] minor fixes
+ata-update-63.dpatch:#   
+ata-update-63.dpatch:#   Add support for ioctl handling.
+ata-update-63.dpatch:#   Remove incorrect comment.
+ata-update-63.dpatch:# 
+ata-update-63.dpatch:# drivers/scsi/ahci.c
+ata-update-63.dpatch:#   2004/11/16 19:01:47-05:00 jgarzik at pobox.com +1 -4
+ata-update-63.dpatch:#   [libata ahci] minor fixes
+ata-update-63.dpatch:#   
+ata-update-63.dpatch:#   Add support for ioctl handling.
+ata-update-63.dpatch:#   Remove incorrect comment.
+ata-update-63.dpatch:# 
+ata-update-64.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-64.dpatch:#
+ata-update-64.dpatch:# ChangeSet
+ata-update-64.dpatch:#   2004/12/07 18:54:34-05:00 jgarzik at pobox.com 
+ata-update-64.dpatch:#   [libata] only DMA map data for DMA commands (fix >=4GB bug)
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   libata made the assumption that (for PIO commands in this case)
+ata-update-64.dpatch:#   it could modify DMA memory at the kernel-virtual address, after
+ata-update-64.dpatch:#   mapping this.  This is incorrect, and fails on e.g. platforms that
+ata-update-64.dpatch:#   copy DMA memory back and forth (swiotlb on Intel EM64T and IA64).
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   Remove this assumption by ensuring that we only call the DMA mapping
+ata-update-64.dpatch:#   routines if we really are going to use DMA for data xfer.
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   Also:  remove a bogus WARN_ON() in ata_sg_init_one() which caused
+ata-update-64.dpatch:#   bug reports (but no problems).
+ata-update-64.dpatch:# 
+ata-update-64.dpatch:# drivers/scsi/ahci.c
+ata-update-64.dpatch:#   2004/12/07 18:54:23-05:00 jgarzik at pobox.com +2 -1
+ata-update-64.dpatch:#   [libata] only DMA map data for DMA commands (fix >=4GB bug)
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   libata made the assumption that (for PIO commands in this case)
+ata-update-64.dpatch:#   it could modify DMA memory at the kernel-virtual address, after
+ata-update-64.dpatch:#   mapping this.  This is incorrect, and fails on e.g. platforms that
+ata-update-64.dpatch:#   copy DMA memory back and forth (swiotlb on Intel EM64T and IA64).
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   Remove this assumption by ensuring that we only call the DMA mapping
+ata-update-64.dpatch:#   routines if we really are going to use DMA for data xfer.
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   Also:  remove a bogus WARN_ON() in ata_sg_init_one() which caused
+ata-update-64.dpatch:#   bug reports (but no problems).
+ata-update-64.dpatch:# 
+ata-update-64.dpatch:# drivers/scsi/libata-core.c
+ata-update-64.dpatch:#   2004/12/07 18:54:23-05:00 jgarzik at pobox.com +34 -8
+ata-update-64.dpatch:#   [libata] only DMA map data for DMA commands (fix >=4GB bug)
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   libata made the assumption that (for PIO commands in this case)
+ata-update-64.dpatch:#   it could modify DMA memory at the kernel-virtual address, after
+ata-update-64.dpatch:#   mapping this.  This is incorrect, and fails on e.g. platforms that
+ata-update-64.dpatch:#   copy DMA memory back and forth (swiotlb on Intel EM64T and IA64).
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   Remove this assumption by ensuring that we only call the DMA mapping
+ata-update-64.dpatch:#   routines if we really are going to use DMA for data xfer.
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   Also:  remove a bogus WARN_ON() in ata_sg_init_one() which caused
+ata-update-64.dpatch:#   bug reports (but no problems).
+ata-update-64.dpatch:# 
+ata-update-64.dpatch:# include/linux/libata.h
+ata-update-64.dpatch:#   2004/12/07 18:54:23-05:00 jgarzik at pobox.com +1 -0
+ata-update-64.dpatch:#   [libata] only DMA map data for DMA commands (fix >=4GB bug)
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   libata made the assumption that (for PIO commands in this case)
+ata-update-64.dpatch:#   it could modify DMA memory at the kernel-virtual address, after
+ata-update-64.dpatch:#   mapping this.  This is incorrect, and fails on e.g. platforms that
+ata-update-64.dpatch:#   copy DMA memory back and forth (swiotlb on Intel EM64T and IA64).
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   Remove this assumption by ensuring that we only call the DMA mapping
+ata-update-64.dpatch:#   routines if we really are going to use DMA for data xfer.
+ata-update-64.dpatch:#   
+ata-update-64.dpatch:#   Also:  remove a bogus WARN_ON() in ata_sg_init_one() which caused
+ata-update-64.dpatch:#   bug reports (but no problems).
+ata-update-64.dpatch:# 
+ata-update-65.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-65.dpatch:#
+ata-update-65.dpatch:# ChangeSet
+ata-update-65.dpatch:#   2004/12/07 19:23:59-05:00 dougg at torque.net 
+ata-update-65.dpatch:#   [PATCH] off-by-1 libata-scsi INQUIRY VPD pages 0x80 and 0x83
+ata-update-65.dpatch:#   
+ata-update-65.dpatch:#   I have some code (in sginfo) that requests the first 4 bytes
+ata-update-65.dpatch:#   of SCSI INQUIRY VPD pages to get their length then asks for
+ata-update-65.dpatch:#   that exact length in a follow up request to fetch the payload.
+ata-update-65.dpatch:#   Just like I saw with 36 byte standard INQUIRYs (no fixed)
+ata-update-65.dpatch:#   I get a buffer  full or zeroes.
+ata-update-65.dpatch:#   
+ata-update-65.dpatch:#   BTW SCSI standards dictate that in situations where the allocation
+ata-update-65.dpatch:#   length (in the cdb) is less than what is needed that what can be
+ata-update-65.dpatch:#   sent shall be sent (i.e. truncated and without any error indication
+ata-update-65.dpatch:#   or modification to the part of the response returned).
+ata-update-65.dpatch:#   In other words it is up the the application client to take remedial
+ata-update-65.dpatch:#   action.
+ata-update-65.dpatch:#   
+ata-update-65.dpatch:#   Changelog:
+ata-update-65.dpatch:#      - fix off-by-1 allocation length issue with SCSI
+ata-update-65.dpatch:#        INQUIRY VPD pages 0x80 and 0x83
+ata-update-65.dpatch:#   
+ata-update-65.dpatch:#   Signed-off-by: Jeff Garzik <jgarzik at pobox.com>
+ata-update-65.dpatch:# 
+ata-update-65.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-65.dpatch:#   2004/11/26 04:13:03-05:00 dougg at torque.net +2 -2
+ata-update-65.dpatch:#   off-by-1 libata-scsi INQUIRY VPD pages 0x80 and 0x83
+ata-update-65.dpatch:# 
+ata-update-66.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-66.dpatch:#
+ata-update-66.dpatch:# ChangeSet
+ata-update-66.dpatch:#   2004/12/22 18:58:50-05:00 jgarzik at pobox.com 
+ata-update-66.dpatch:#   [libata sata_nv] fix dev detect by removing sata-reset flag
+ata-update-66.dpatch:#   
+ata-update-66.dpatch:#   Remove ATA_FLAG_SATA_RESET.  See comment in code and
+ata-update-66.dpatch:#   http://bugme.osdl.org/show_bug.cgi?id=3352 for more details.
+ata-update-66.dpatch:#   
+ata-update-66.dpatch:#   This problem needs more investigation.  Removing the flag
+ata-update-66.dpatch:#   appears to fix the problems in the field, so it's the best
+ata-update-66.dpatch:#   temporary solution.
+ata-update-66.dpatch:# 
+ata-update-66.dpatch:# drivers/scsi/sata_nv.c
+ata-update-66.dpatch:#   2004/12/22 18:58:44-05:00 jgarzik at pobox.com +9 -1
+ata-update-66.dpatch:#   [libata sata_nv] fix dev detect by removing sata-reset flag
+ata-update-66.dpatch:#   
+ata-update-66.dpatch:#   Remove ATA_FLAG_SATA_RESET.  See comment in code and
+ata-update-66.dpatch:#   http://bugme.osdl.org/show_bug.cgi?id=3352 for more details.
+ata-update-66.dpatch:#   
+ata-update-66.dpatch:#   This problem needs more investigation.  Removing the flag
+ata-update-66.dpatch:#   appears to fix the problems in the field, so it's the best
+ata-update-66.dpatch:#   temporary solution.
+ata-update-66.dpatch:# 
+ata-update-67.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-67.dpatch:#
+ata-update-67.dpatch:# ChangeSet
+ata-update-67.dpatch:#   2004/07/10 10:29:46-04:00 jgarzik at pobox.com 
+ata-update-67.dpatch:#   [libata ata_piix] make sure AHCI is disabled, if h/w is used by this driver
+ata-update-67.dpatch:#   
+ata-update-67.dpatch:#   AHCI must be disabled if we are to have access to taskfile registers.
+ata-update-67.dpatch:# 
+ata-update-67.dpatch:# drivers/scsi/ata_piix.c
+ata-update-67.dpatch:#   2004/07/10 10:29:40-04:00 jgarzik at pobox.com +58 -6
+ata-update-67.dpatch:#   [libata ata_piix] make sure AHCI is disabled, if h/w is used by this driver
+ata-update-67.dpatch:#   
+ata-update-67.dpatch:#   AHCI must be disabled if we are to have access to taskfile registers.
+ata-update-67.dpatch:# 
+ata-update-68.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-68.dpatch:#
+ata-update-68.dpatch:# ChangeSet
+ata-update-68.dpatch:#   2004/10/15 00:55:45-04:00 bzolnier at gmail.com 
+ata-update-68.dpatch:#   [libata] do not memset() SCSI request buf in a get-reference style function
+ata-update-68.dpatch:#   
+ata-update-68.dpatch:#   fixes INQUIRY command handling for ATAPI.
+ata-update-68.dpatch:#   
+ata-update-68.dpatch:#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+ata-update-68.dpatch:# 
+ata-update-68.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-68.dpatch:#   2004/10/14 17:04:45-04:00 bzolnier at gmail.com +1 -1
+ata-update-68.dpatch:#   [libata] do not memset() SCSI request buf in a get-reference style function
+ata-update-68.dpatch:# 
+ata-update-69.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-69.dpatch:#
+ata-update-69.dpatch:# ChangeSet
+ata-update-69.dpatch:#   2004/08/27 19:13:32-07:00 viro at www.linux.org.uk 
+ata-update-69.dpatch:#   [PATCH] 64bit portability fixes (pointer-to-int stuff)
+ata-update-69.dpatch:#   
+ata-update-69.dpatch:#   Signed-off-by: Al Viro <viro at parcelfarce.linux.org.uk>
+ata-update-69.dpatch:#   Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+ata-update-69.dpatch:# 
+ata-update-69.dpatch:# drivers/media/dvb/frontends/dst.c
+ata-update-69.dpatch:#   2004/08/27 13:05:05-07:00 viro at www.linux.org.uk +3 -3
+ata-update-69.dpatch:#   64bit portability fixes (pointer-to-int stuff)
+ata-update-69.dpatch:# 
+ata-update-69.dpatch:# drivers/media/video/zoran_driver.c
+ata-update-69.dpatch:#   2004/08/27 13:05:05-07:00 viro at www.linux.org.uk +2 -2
+ata-update-69.dpatch:#   64bit portability fixes (pointer-to-int stuff)
+ata-update-69.dpatch:# 
+ata-update-69.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-69.dpatch:#   2004/08/27 13:05:05-07:00 viro at www.linux.org.uk +1 -1
+ata-update-69.dpatch:#   64bit portability fixes (pointer-to-int stuff)
+ata-update-69.dpatch:# 
+ata-update-69.dpatch:# sound/oss/wavfront.c
+ata-update-69.dpatch:#   2004/08/27 13:05:05-07:00 viro at www.linux.org.uk +2 -2
+ata-update-69.dpatch:#   64bit portability fixes (pointer-to-int stuff)
+ata-update-69.dpatch:# 
+ata-update-70.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-70.dpatch:#
+ata-update-70.dpatch:# ChangeSet
+ata-update-70.dpatch:#   2004/08/18 01:27:55-04:00 jgarzik at pobox.com 
+ata-update-70.dpatch:#   [libata] fix error recovery reference count
+ata-update-70.dpatch:#   
+ata-update-70.dpatch:#   This bug could potentially lead to soft hangs (processes stuck in D
+ata-update-70.dpatch:#   state) if an error occurred.
+ata-update-70.dpatch:#   
+ata-update-70.dpatch:#   Yet another undocumented nuance of the ->eh_strategy_handler.
+ata-update-70.dpatch:#   
+ata-update-70.dpatch:#   Thanks to excellent detective work by Brad Campbell tracking this down.
+ata-update-70.dpatch:# 
+ata-update-70.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-70.dpatch:#   2004/08/18 01:27:48-04:00 jgarzik at pobox.com +6 -0
+ata-update-70.dpatch:#   [libata] fix error recovery reference count
+ata-update-70.dpatch:#   
+ata-update-70.dpatch:#   This bug could potentially lead to soft hangs (processes stuck in D
+ata-update-70.dpatch:#   state) if an error occurred.
+ata-update-70.dpatch:#   
+ata-update-70.dpatch:#   Yet another undocumented nuance of the ->eh_strategy_handler.
+ata-update-70.dpatch:#   
+ata-update-70.dpatch:#   Thanks to excellent detective work by Brad Campbell tracking this down.
+ata-update-70.dpatch:# 
+ata-update-71.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-71.dpatch:#
+ata-update-71.dpatch:# ChangeSet
+ata-update-71.dpatch:#   2004/10/26 03:42:24-04:00 jgarzik at pobox.com 
+ata-update-71.dpatch:#   [libata] return ENOTTY rather than EOPNOTSUPP for unknown-ioctl
+ata-update-71.dpatch:# 
+ata-update-71.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-71.dpatch:#   2004/10/26 03:42:18-04:00 jgarzik at pobox.com +1 -1
+ata-update-71.dpatch:#   [libata] return ENOTTY rather than EOPNOTSUPP for unknown-ioctl
+ata-update-71.dpatch:# 
+ata-update-72.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-72.dpatch:#
+ata-update-72.dpatch:# ChangeSet
+ata-update-72.dpatch:#   2004/10/26 19:39:53-04:00 jgarzik at pobox.com 
+ata-update-72.dpatch:#   [libata] use kunmap_atomic() correctly
+ata-update-72.dpatch:# 
+ata-update-72.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-72.dpatch:#   2004/10/26 19:39:47-04:00 jgarzik at pobox.com +4 -4
+ata-update-72.dpatch:#   [libata] use kunmap_atomic() correctly
+ata-update-72.dpatch:# 
+ata-update-73.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-73.dpatch:#
+ata-update-73.dpatch:# ChangeSet
+ata-update-73.dpatch:#   2004/08/18 01:30:37-04:00 dougg at torque.net 
+ata-update-73.dpatch:#   [libata] fix INQUIRY handling
+ata-update-73.dpatch:#   
+ata-update-73.dpatch:#   
+ata-update-73.dpatch:#   Changes:
+ata-update-73.dpatch:#      - send vendor, product and rev strings back for 36 byte
+ata-update-73.dpatch:#        INQUIRYs
+ata-update-73.dpatch:#      - set the additional length field to indicate 96 byte
+ata-update-73.dpatch:#        response is available 
+ata-update-73.dpatch:# 
+ata-update-73.dpatch:# drivers/scsi/libata-scsi.c
+ata-update-73.dpatch:#   2004/08/18 01:30:31-04:00 dougg at torque.net +2 -2
+ata-update-73.dpatch:#   [libata] fix INQUIRY handling
+ata-update-73.dpatch:#   
+ata-update-73.dpatch:#   
+ata-update-73.dpatch:#   Changes:
+ata-update-73.dpatch:#      - send vendor, product and rev strings back for 36 byte
+ata-update-73.dpatch:#        INQUIRYs
+ata-update-73.dpatch:#      - set the additional length field to indicate 96 byte
+ata-update-73.dpatch:#        response is available 
+ata-update-73.dpatch:# 
+ata-update-74.dpatch:# backported only the hdreg.h bit to Debian's kernel-source-2.6.8
+ata-update-74.dpatch:#   dann frazier <dannf at hp.com>
+ata-update-74.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-74.dpatch:#
+ata-update-74.dpatch:# ChangeSet
+ata-update-74.dpatch:#   2004/12/13 08:31:34-08:00 trini at kernel.crashing.org 
+ata-update-74.dpatch:#   [PATCH] Add missing __KERNEL__ (or other) protections
+ata-update-74.dpatch:#   
+ata-update-74.dpatch:#   As of 2.6.10-rc3, the following is needed to allow various userland
+ata-update-74.dpatch:#   packages (sysvinit, dhcp, ppp, libcap, libpcap, lilo) to compile as parts
+ata-update-74.dpatch:#   that userland needs (e.g.  for ioctls) is in files with stuff userland
+ata-update-74.dpatch:#   isn't allowed to see.
+ata-update-74.dpatch:#   
+ata-update-74.dpatch:#   This adds __KERNEL__ around <linux/ata.h> and some defines (<linux/ata.h>
+ata-update-74.dpatch:#   isn't needed by userland, and is unhappy right now).  sysvinit and some
+ata-update-74.dpatch:#   other packages need <linux/hdreg.h> for HDIO_DRIVE_CMD and other IOCTL
+ata-update-74.dpatch:#   things.  In <linux/types.h> we were unsafely typedef'ing __le64/__be64 as
+ata-update-74.dpatch:#   __u64 only exists when __GNUC__ && !__STRICT_ANSI__ (causing libcap to
+ata-update-74.dpatch:#   fail, for example).  Finally, <asm/atomic.h> provides routines userland
+ata-update-74.dpatch:#   simply cannot use on all arches, but <linux/filter.h> is needed by iputils
+ata-update-74.dpatch:#   for example.  While not all arches put __KERNEL__ around their header, on
+ata-update-74.dpatch:#   MIPS including this header currently blows up the build.
+ata-update-74.dpatch:#   
+ata-update-74.dpatch:#   Signed-off-by: Tom Rini <trini at kernel.crashing.org>
+ata-update-74.dpatch:#   Signed-off-by: Andrew Morton <akpm at osdl.org>
+ata-update-74.dpatch:#   Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+ata-update-74.dpatch:# 
+ata-update-74.dpatch:# include/linux/filter.h
+ata-update-74.dpatch:#   2004/12/13 02:47:28-08:00 trini at kernel.crashing.org +2 -0
+ata-update-74.dpatch:#   Add missing __KERNEL__ (or other) protections
+ata-update-74.dpatch:# 
+ata-update-74.dpatch:# include/linux/hdreg.h
+ata-update-74.dpatch:#   2004/12/13 02:47:28-08:00 trini at kernel.crashing.org +2 -1
+ata-update-74.dpatch:#   Add missing __KERNEL__ (or other) protections
+ata-update-74.dpatch:# 
+ata-update-74.dpatch:# include/linux/types.h
+ata-update-74.dpatch:#   2004/12/13 02:47:28-08:00 trini at kernel.crashing.org +2 -0
+ata-update-74.dpatch:#   Add missing __KERNEL__ (or other) protections
+ata-update-74.dpatch:# 
+ata-update-75.dpatch:# This is a BitKeeper generated diff -Nru style patch.
+ata-update-75.dpatch:#
+ata-update-75.dpatch:# ChangeSet
+ata-update-75.dpatch:#   2004/11/13 14:43:08-05:00 jgarzik at pobox.com 
+ata-update-75.dpatch:#   Parenthize nth_page() macro arg, in linux/mm.h.
+ata-update-75.dpatch:# 
+ata-update-75.dpatch:# include/linux/mm.h
+ata-update-75.dpatch:#   2004/11/13 14:41:23-05:00 jgarzik at pobox.com +1 -1
+ata-update-75.dpatch:#   Parenthize nth_page() macro arg, in linux/mm.h.
+ata-update-75.dpatch:# 

Modified: people/dannf/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-16sarge5dannf1
==============================================================================
--- people/dannf/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-16sarge5dannf1	(original)
+++ people/dannf/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-16sarge5dannf1	Mon Sep 18 22:12:12 2006
@@ -6,3 +6,4 @@
 + drivers-block-ioctl-enotty.dpatch
 + drivers-net-e1000-6.2.15.dpatch
 + cciss_2.6.2_to_2.6.10.dpatch
++ ata-update-to-2.6.10.dpatch



More information about the Kernel-svn-changes mailing list