diff options
author | Rod Whitby <rod@whitby.id.au> | 2006-02-24 22:41:46 +0000 |
---|---|---|
committer | OpenEmbedded Project <openembedded-devel@lists.openembedded.org> | 2006-02-24 22:41:46 +0000 |
commit | 76945f6290afc35fbb8f23ba907947396e7dd632 (patch) | |
tree | ec748eda777a39af662e574cd780b95c913c112d | |
parent | 98f3a297f2cbda11a6df717652c82521ddbb63ed (diff) |
ixp4xx-kernel: Added support for DSM-G600, and updated to 2.6.16-rc4-git5
29 files changed, 1353 insertions, 17974 deletions
diff --git a/conf/distro/slugos.conf b/conf/distro/slugos.conf index 3b094d769d..2273aca31a 100644 --- a/conf/distro/slugos.conf +++ b/conf/distro/slugos.conf @@ -170,7 +170,7 @@ PREFERRED_VERSION_glibc ?= "2.3.5+cvs20050627" # Select the correct versions of the kernel and modules (these are the # defaults, override in the conf/distro top-level distro file). PREFERRED_PROVIDER_virtual/kernel ?= "ixp4xx-kernel" -PREFERRED_VERSION_ixp4xx-kernel ?= "2.6.15.2" +PREFERRED_VERSION_ixp4xx-kernel ?= "2.6.16-rc4-git5" # Built-in ethernet modules PREFERRED_PROVIDER_virtual/ixp-eth ?= "ixp400-eth" diff --git a/packages/linux/ixp4xx-kernel.inc b/packages/linux/ixp4xx-kernel.inc index 41ff745e71..52f216438a 100644 --- a/packages/linux/ixp4xx-kernel.inc +++ b/packages/linux/ixp4xx-kernel.inc @@ -297,6 +297,20 @@ pkg_postrm_kernel-image-nas100d () { update-alternatives --remove ${KERNEL_IMAGETYPE} /${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE}-nas100d${ARCH_BYTE_SEX}-${KERNEL_RELEASE} || true } +# The correct settings for the DSMG600 board: +dsmg600_MACHID = "964" +PACKAGES += "kernel-image-dsmg600" +PKG_kernel-image-dsmg600 = "kernel-image-${KERNEL_VERSION}" +PACKAGE_ARCH_kernel-image-dsmg600 = "dsmg600${ARCH_BYTE_SEX}" +DESCRIPTION_kernel-image-dsmg600 = "Linux kernel for the D-Link DSM-G600" +FILES_kernel-image-dsmg600 = "/${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE}-dsmg600${ARCH_BYTE_SEX}-${KERNEL_RELEASE}" +pkg_postinst_kernel-image-dsmg600 () { + update-alternatives --install /${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE} ${KERNEL_IMAGETYPE} /${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE}-dsmg600${ARCH_BYTE_SEX}-${KERNEL_RELEASE} ${KERNEL_PRIORITY} || true +} +pkg_postrm_kernel-image-dsmg600 () { + update-alternatives --remove ${KERNEL_IMAGETYPE} /${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE}-dsmg600${ARCH_BYTE_SEX}-${KERNEL_RELEASE} || true +} + #FIXUP: the correct instructions to copy the kernel prepended with the le fixup #FIXME: do a fixup for BE too... FIXUP_armeb = "cp$" @@ -345,6 +359,7 @@ do_install_append() { install_image 'ds101${ARCH_BYTE_SEX}' '${ds101_MACHID}' install_image 'loft${ARCH_BYTE_SEX}' '${loft_MACHID}' install_image 'nas100d${ARCH_BYTE_SEX}' '${nas100d_MACHID}' + install_image 'dsmg600${ARCH_BYTE_SEX}' '${dsmg600_MACHID}' } do_deploy[dirs] = "${S}" @@ -362,6 +377,7 @@ do_deploy() { deploy_image 'ds101${ARCH_BYTE_SEX}' '${ds101_MACHID}' deploy_image 'loft${ARCH_BYTE_SEX}' '${loft_MACHID}' deploy_image 'nas100d${ARCH_BYTE_SEX}' '${nas100d_MACHID}' + deploy_image 'dsmg600${ARCH_BYTE_SEX}' '${dsmg600_MACHID}' } addtask deploy before do_build after do_compile diff --git a/packages/linux/ixp4xx-kernel/2.6.16/05-patch-2.6.16-rc2-ide2 b/packages/linux/ixp4xx-kernel/2.6.16/05-patch-2.6.16-rc2-ide2 deleted file mode 100644 index 3ea46331f6..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/05-patch-2.6.16-rc2-ide2 +++ /dev/null @@ -1,16885 +0,0 @@ -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/arch/i386/pci/fixup.c linux-2.6.16-rc2/arch/i386/pci/fixup.c ---- linux.vanilla-2.6.16-rc2/arch/i386/pci/fixup.c 2006-02-06 12:21:33.000000000 +0000 -+++ linux-2.6.16-rc2/arch/i386/pci/fixup.c 2006-02-01 14:49:17.000000000 +0000 -@@ -74,52 +74,6 @@ - } - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, pci_fixup_ncr53c810); - --static void __devinit pci_fixup_ide_bases(struct pci_dev *d) --{ -- int i; -- -- /* -- * PCI IDE controllers use non-standard I/O port decoding, respect it. -- */ -- if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) -- return; -- DBG("PCI: IDE base address fixup for %s\n", pci_name(d)); -- for(i=0; i<4; i++) { -- struct resource *r = &d->resource[i]; -- if ((r->start & ~0x80) == 0x374) { -- r->start |= 2; -- r->end = r->start; -- } -- } --} --DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); -- --static void __devinit pci_fixup_ide_trash(struct pci_dev *d) --{ -- int i; -- -- /* -- * Runs the fixup only for the first IDE controller -- * (Shai Fultheim - shai@ftcon.com) -- */ -- static int called = 0; -- if (called) -- return; -- called = 1; -- -- /* -- * There exist PCI IDE controllers which have utter garbage -- * in first four base registers. Ignore that. -- */ -- DBG("PCI: IDE base address trash cleared for %s\n", pci_name(d)); -- for(i=0; i<4; i++) -- d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0; --} --DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, pci_fixup_ide_trash); --DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_fixup_ide_trash); --DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, pci_fixup_ide_trash); --DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_9, pci_fixup_ide_trash); -- - static void __devinit pci_fixup_latency(struct pci_dev *d) - { - /* -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/cdrom/cdrom.c linux-2.6.16-rc2/drivers/cdrom/cdrom.c ---- linux.vanilla-2.6.16-rc2/drivers/cdrom/cdrom.c 2006-02-06 12:21:34.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/cdrom/cdrom.c 2006-01-17 16:34:19.000000000 +0000 -@@ -1131,7 +1131,8 @@ - This ensures that the drive gets unlocked after a mount fails. This - is a goto to avoid bloating the driver with redundant code. */ - clean_up_and_return: -- cdinfo(CD_OPEN, "open failed.\n"); -+ /* Don't log this, its a perfectly normal user occurence */ -+ /* cdinfo(CD_WARNING, "open failed.\n"); */ - if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) { - cdo->lock_door(cdi, 0); - cdinfo(CD_OPEN, "door unlocked.\n"); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/pci/probe.c linux-2.6.16-rc2/drivers/pci/probe.c ---- linux.vanilla-2.6.16-rc2/drivers/pci/probe.c 2006-02-06 12:21:35.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/pci/probe.c 2006-02-01 15:56:28.000000000 +0000 -@@ -627,6 +627,7 @@ - static int pci_setup_device(struct pci_dev * dev) - { - u32 class; -+ u16 cmd; - - sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), - dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); -@@ -654,6 +655,31 @@ - pci_read_bases(dev, 6, PCI_ROM_ADDRESS); - pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor); - pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); -+ -+ /* -+ * Do the ugly legacy mode stuff here rather than broken chip -+ * quirk code. Legacy mode ATA controllers have fixed -+ * addresses. These are not always echoed in BAR0-3, and -+ * BAR0-3 in a few cases contain junk! -+ */ -+ if (class == PCI_CLASS_STORAGE_IDE) { -+ u8 progif; -+ pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); -+ if ((progif & 5) != 5) { -+ dev->resource[0].start = 0x1F0; -+ dev->resource[0].end = 0x1F7; -+ dev->resource[0].flags = IORESOURCE_IO; -+ dev->resource[1].start = 0x3F6; -+ dev->resource[1].end = 0x3F6; -+ dev->resource[1].flags = IORESOURCE_IO; -+ dev->resource[2].start = 0x170; -+ dev->resource[2].end = 0x177; -+ dev->resource[2].flags = IORESOURCE_IO; -+ dev->resource[3].start = 0x376; -+ dev->resource[3].end = 0x376; -+ dev->resource[3].flags = IORESOURCE_IO; -+ } -+ } - break; - - case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ -@@ -687,6 +713,10 @@ - dev->class = PCI_CLASS_NOT_DEFINED; - } - -+ /* BIOS enabled, so assume there is a good reason */ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ if(cmd & PCI_COMMAND_MASTER) -+ dev->is_enabled = 1; - /* We found a fine healthy device, go go go... */ - return 0; - } -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/ata_generic.c linux-2.6.16-rc2/drivers/scsi/ata_generic.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/ata_generic.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/ata_generic.c 2006-02-07 13:47:27.337665568 +0000 -@@ -0,0 +1,242 @@ -+/* -+ * ata_generic.c - Generic PATA/SATA controller driver. -+ * Copyright 2005 Red Hat Inc <alan@redhat.com>, all rights reserved. -+ * -+ * Elements from ide/pci/generic.c -+ * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> -+ * Portions (C) Copyright 2002 Red Hat Inc <alan@redhat.com> -+ * -+ * May be copied or modified under the terms of the GNU General Public License -+ * -+ * Driver for PCI IDE interfaces implementing the standard bus mastering -+ * interface functionality. This assumes the BIOS did the drive set up and -+ * tuning for us. By default we do not grab all IDE class devices as they -+ * may have other drivers or need fixups to avoid problems. Instead we keep -+ * a default list of stuff without documentation/driver that appears to -+ * work. -+ */ -+ -+#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 "scsi.h" -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "generic" -+#define DRV_VERSION "0.1" -+ -+/* -+ * A generic parallel ATA driver using libata -+ */ -+ -+static void genpata_phy_reset(struct ata_port *ap) -+{ -+ /* We know the BIOS already did the mode work. Don't tempt any -+ one else to "fix" things */ -+ ap->cbl = ATA_CBL_PATA80; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * genpata_set_mode - mode setting -+ * @ap: interface to set up -+ * -+ * Use a non standard set_mode function. We don't want to be tuned. -+ * The BIOS configured everything. Our job is not to fiddle. We -+ * read the dma enabled bits from the PCI configuration of the device -+ * and respect them. -+ */ -+ -+static void genpata_set_mode(struct ata_port *ap) -+{ -+ int dma_enabled; -+ int i; -+ -+ /* Bits 5 and 6 indicate if DMA is active on master/slave */ -+ dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *dev = &ap->device[i]; -+ if (ata_dev_present(dev)) { -+ /* We don't really care */ -+ dev->pio_mode = XFER_PIO_0; -+ dev->dma_mode = XFER_MW_DMA_0; -+ /* We do need the right mode information for DMA or PIO -+ and this comes from the current configuration flags */ -+ /* FIXME: at some point in the future this should become -+ a library helper which reads the disk modes from the -+ disk as well */ -+ if(dma_enabled & (1 << (5 + i))) { -+ dev->xfer_mode = XFER_MW_DMA_0; -+ dev->xfer_shift = ATA_SHIFT_MWDMA; -+ dev->flags &= ~ATA_DFLAG_PIO; -+ } else { -+ dev->xfer_mode = XFER_PIO_0; -+ dev->xfer_shift = ATA_SHIFT_PIO; -+ dev->flags |= ATA_DFLAG_PIO; -+ } -+ } -+ } -+} -+ -+static struct scsi_host_template genpata_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations genpata_port_ops = { -+ .set_mode = genpata_set_mode, -+ -+ .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 = genpata_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .data_xfer = ata_pio_data_xfer, -+ -+ .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, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int ide_generic_all; /* Set to claim all devices */ -+ -+static int __init ide_generic_all_on(char *unused) -+{ -+ ide_generic_all = 1; -+ printk(KERN_INFO "ATA generic will claim all unknown PCI IDE class storage controllers.\n"); -+ return 1; -+} -+ -+__setup("all-generic-ide", ide_generic_all_on); -+ -+/** -+ * pata_generic_init - attach generic IDE -+ * @dev: PCI device found -+ * @id: match entry -+ * -+ * Called each time a matching IDE interface is found. We check if the -+ * interface is one we wish to claim and if so we perform any chip -+ * specific hacks then let the ATA layer do the heavy lifting. -+ */ -+ -+static int pata_generic_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ u16 command; -+ static struct ata_port_info info = { -+ .sht = &genpata_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_IRQ_MASK, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &genpata_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ /* Don't use the generic entry unless instructed to do so */ -+ if (id->driver_data == 1 && ide_generic_all == 0) -+ return -ENODEV; -+ -+ /* Devices that need care */ -+ if (dev->vendor == PCI_VENDOR_ID_UMC && -+ dev->device == PCI_DEVICE_ID_UMC_UM8886A && -+ (!(PCI_FUNC(dev->devfn) & 1))) -+ return -ENODEV; -+ -+ if (dev->vendor == PCI_VENDOR_ID_OPTI && -+ dev->device == PCI_DEVICE_ID_OPTI_82C558 && -+ (!(PCI_FUNC(dev->devfn) & 1))) -+ return -ENODEV; -+ -+ /* Don't re-enable devices in generic mode or we will break some -+ motherboards with disabled and unused IDE controllers */ -+ pci_read_config_word(dev, PCI_COMMAND, &command); -+ if (!(command & PCI_COMMAND_IO)) -+ return -ENODEV; -+ -+ if (dev->vendor == PCI_VENDOR_ID_AL) -+ ata_pci_clear_simplex(dev); -+ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id pata_generic[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_NS,PCI_DEVICE_ID_NS_87410),}, -+ { PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2), }, -+ /* Must come last. If you add entries adjust this table appropriately */ -+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1}, -+ { 0, }, -+}; -+ -+static struct pci_driver pata_generic_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = pata_generic, -+ .probe = pata_generic_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init pata_generic_init(void) -+{ -+ return pci_module_init(&pata_generic_pci_driver); -+} -+ -+ -+static void __exit pata_generic_exit(void) -+{ -+ pci_unregister_driver(&pata_generic_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for generic ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, pata_generic); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(pata_generic_init); -+module_exit(pata_generic_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/ata_piix.c linux-2.6.16-rc2/drivers/scsi/ata_piix.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/ata_piix.c 2006-02-06 12:21:35.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/ata_piix.c 2006-02-06 12:28:58.000000000 +0000 -@@ -91,9 +91,10 @@ - #include <linux/device.h> - #include <scsi/scsi_host.h> - #include <linux/libata.h> -+#include <linux/ata.h> - - #define DRV_NAME "ata_piix" --#define DRV_VERSION "1.05" -+#define DRV_VERSION "1.05-ac1" - - enum { - PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ -@@ -122,6 +123,17 @@ - piix4_pata = 2, - ich6_sata = 3, - ich6_sata_ahci = 4, -+ ich0_pata = 5, -+ ich2_pata = 6, -+ ich3_pata = 7, -+ ich4_pata = 8, -+ cich_pata = 9, -+ piix3_pata = 10, -+ esb_pata = 11, -+ ich_pata = 12, -+ ich6_pata = 13, -+ ich7_pata = 14, -+ esb2_pata = 15, - - PIIX_AHCI_DEVICE = 6, - }; -@@ -130,20 +142,69 @@ - const struct pci_device_id *ent); - - static void piix_pata_phy_reset(struct ata_port *ap); -+static void ich_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); - static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); -+static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev); - - static unsigned int in_module_init = 1; - - static const struct pci_device_id piix_pci_tbl[] = { - #ifdef ATA_ENABLE_PATA -+#if 0 -+ /* Neptune and earlier are simple PIO */ -+ /* 430HX and friends. MWDMA */ -+ { 0x8086, 0x122e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix3_pata }, -+ { 0x8086, 0x1230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix3_pata }, -+ /* Intel PIIX3 */ -+ { 0x8086, 0x7010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix3_pata }, -+#endif -+ /* Intel PIIX4 for the 430TX/440BX/MX chipset: UDMA 33 */ -+ /* Also PIIX4E (fn3 rev 2) and PIIX4M (fn3 rev 3) */ - { 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, - { 0x8086, 0x24db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, - { 0x8086, 0x25a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, -+ /* Intel PIIX4 */ -+ { 0x8086, 0x7199, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, -+ /* Intel PIIX4 */ -+ { 0x8086, 0x7601, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, -+ /* Intel PIIX */ -+ { 0x8086, 0x84CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, -+ /* Intel ICH (i810, i815, i840) UDMA 66*/ -+ { 0x8086, 0x2411, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata }, -+ /* Intel ICH0 : UDMA 33*/ -+ { 0x8086, 0x2421, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich0_pata }, -+ /* Intel ICH2M */ -+ { 0x8086, 0x244A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich2_pata }, -+ /* Intel ICH2 (i810E2, i845, 850, 860) UDMA 100 */ -+ { 0x8086, 0x244B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich2_pata }, -+ /* Intel ICH3M */ -+ { 0x8086, 0x248A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich3_pata }, -+ /* Intel ICH3 (E7500/1) UDMA 100 */ -+ { 0x8086, 0x248B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich3_pata }, -+#if 0 -+ { 0x8086, 0x24C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, dunno_pata }, -+#endif -+ /* Intel ICH4 (i845GV, i845E, i852, i855) UDMA 100 */ -+ { 0x8086, 0x24CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich4_pata }, -+ { 0x8086, 0x24CB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich4_pata }, -+ /* Intel ICH5 */ -+ { 0x8086, 0x24DB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, -+ /* C-ICH (i810E2) */ -+ { 0x8086, 0x245B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, cich_pata }, -+ /* ESB (855GME/875P + 6300ESB) UDMA 100 */ -+ { 0x8086, 0x25A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_pata }, -+ /* ICH6 (and 6) (i915) UDMA 100 */ -+ { 0x8086, 0x266F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_pata }, -+ /* ICH7/7-R (i945, i975) UDMA 100*/ -+ { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_pata }, -+ { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb2_pata }, - #endif -- -- /* NOTE: The following PCI ids must be kept in sync with the -+ /* -+ * SATA ports -+ * -+ * NOTE: The following PCI ids must be kept in sync with the - * list in drivers/pci/quirks.c. - */ - -@@ -213,6 +274,40 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations ich_pata_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = piix_set_piomode, -+ .set_dmamode = ich_set_dmamode, -+ -+ .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 = ich_pata_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ -+ .data_xfer = ata_pio_data_xfer, - - .eng_timeout = ata_eng_timeout, - -@@ -242,6 +337,8 @@ - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, - -+ .data_xfer = ata_pio_data_xfer, -+ - .eng_timeout = ata_eng_timeout, - - .irq_handler = ata_interrupt, -@@ -259,13 +356,9 @@ - .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | - PIIX_FLAG_CHECKINTR, - .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, -+ .port_ops = &ich_pata_ops, - }, - - /* ich5_sata */ -@@ -284,11 +377,7 @@ - .sht = &piix_sht, - .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, - .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, - }, -@@ -316,6 +405,116 @@ - .udma_mask = 0x7f, /* udma0-6 */ - .port_ops = &piix_sata_ops, - }, -+ -+ /* ich0_pata */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ -+ .udma_mask = 0x07, /* UDMA33 only */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* ich2_pata */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ -+ .udma_mask = 0x1f, /* UDMA100 */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* ich3_pata */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ -+ .udma_mask = 0x1f, /* UDMA100 */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* ich4_pata */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x1f, /* UDMA100 */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* cich_pata */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x1f, /* UDMA100 */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* piix3_pata */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma1-2 */ -+ .udma_mask = ATA_UDMA_MASK_40C, -+ .port_ops = &piix_pata_ops, -+ }, -+ -+ /* esb_pata */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x1f, /* UDMA100 */ -+ .port_ops = &piix_pata_ops, -+ }, -+ -+ /* ich_pata */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x07, /* UDMA66 */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* ich6_pata */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x3f, /* UDMA133 */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* ich7_pata */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x3f, /* UDMA133 */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* esb2_pata */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x1f, /* UDMA100 -- CHECKME --*/ -+ .port_ops = &ich_pata_ops, -+ }, - }; - - static struct pci_bits piix_enable_bits[] = { -@@ -339,7 +538,7 @@ - * LOCKING: - * None (inherited from caller). - */ --static void piix_pata_cbl_detect(struct ata_port *ap) -+static void ich_pata_cbl_detect(struct ata_port *ap) - { - struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); - u8 tmp, mask; -@@ -366,8 +565,9 @@ - * piix_pata_phy_reset - Probe specified port on PATA host controller - * @ap: Port to probe - * -- * Probe PATA phy. -- * -+ * Probe PATA phy. Unlike the ICH we have no IOCFG register and -+ * don't do UDMA66+ anyway. -+ - * LOCKING: - * None (inherited from caller). - */ -@@ -381,11 +581,34 @@ - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return; - } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} - -- piix_pata_cbl_detect(ap); - -- ata_port_probe(ap); -+/** -+ * ich_pata_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * Probe PATA phy. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void ich_pata_phy_reset(struct ata_port *ap) -+{ -+ 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; -+ } -+ -+ ich_pata_cbl_detect(ap); -+ ata_port_probe(ap); - ata_bus_reset(ap); - } - -@@ -481,6 +704,13 @@ - unsigned int slave_port = 0x44; - u16 master_data; - u8 slave_data; -+ u8 udma_enable; -+ int control = 0; -+ -+ /* -+ * See Intel Document 298600-004 for the timing programing rules -+ * for ICH controllers. -+ */ - - static const /* ISP RTC */ - u8 timings[][2] = { { 0, 0 }, -@@ -489,20 +719,30 @@ - { 2, 1 }, - { 2, 3 }, }; - -+ if (pio > 2) -+ control |= 1; /* TIME1 enable */ -+ if (ata_pio_need_iordy(adev)) -+ control |= 2; /* IE enable */ -+ -+ /* Intel specifies that the PPE functionality is for disk only */ -+ if (adev->class == ATA_DEV_ATA) -+ control |= 4; /* PPE enable */ -+ - pci_read_config_word(dev, master_port, &master_data); - if (is_slave) { -+ /* Enable SITRE (seperate slave timing register) */ - master_data |= 0x4000; -- /* enable PPE, IE and TIME */ -- master_data |= 0x0070; -+ /* enable PPE1, IE1 and TIME1 as needed */ -+ master_data |= (control << 4); - pci_read_config_byte(dev, slave_port, &slave_data); - slave_data &= (ap->hard_port_no ? 0x0f : 0xf0); -- slave_data |= -- (timings[pio][0] << 2) | -- (timings[pio][1] << (ap->hard_port_no ? 4 : 0)); -+ /* Load the timing nibble for this slave */ -+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->hard_port_no ? 4 : 0); - } else { -+ /* Master keeps the bits in a different format */ - master_data &= 0xccf8; -- /* enable PPE, IE and TIME */ -- master_data |= 0x0007; -+ /* Enable PPE, IE and TIME as appropriate */ -+ master_data |= control; - master_data |= - (timings[pio][0] << 12) | - (timings[pio][1] << 8); -@@ -510,84 +750,165 @@ - pci_write_config_word(dev, master_port, master_data); - if (is_slave) - pci_write_config_byte(dev, slave_port, slave_data); -+ -+ /* Ensure the UDMA bit is off - it will be turned back on if -+ UDMA is selected */ -+ -+ if(ap->udma_mask) { -+ pci_read_config_byte(dev, 0x48, &udma_enable); -+ udma_enable &= ~(1 << (2 * ap->hard_port_no + adev->devno)); -+ pci_write_config_byte(dev, 0x48, udma_enable); -+ } - } - - /** -- * piix_set_dmamode - Initialize host controller PATA PIO timings -+ * do_piix_set_dmamode - Initialize host controller PATA PIO timings - * @ap: Port whose timings we are configuring -- * @adev: um -- * @udma: udma mode, 0 - 6 -+ * @adev: device to configure -+ * @isich: True if the device is an ICH and has IOCFG registers - * -- * Set UDMA mode for device, in host controller PCI config space. -+ * Set MW/UDMA mode for device, in host controller PCI config space. -+ * Note: We know the caller has already set the PIO mode. In doing -+ * so it has correctly set PPE, SITRE, IORDY and TIME1. We rely on that. - * - * LOCKING: - * None (inherited from caller). - */ - --static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, int isich) - { -- 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; -- int a_speed = 3 << (drive_dn * 4); -- int u_flag = 1 << drive_dn; -- int v_flag = 0x01 << drive_dn; -- int w_flag = 0x10 << drive_dn; -- int u_speed = 0; -- int sitre; -- u16 reg4042, reg4a; -- u8 reg48, reg54, reg55; -- -- pci_read_config_word(dev, maslave, ®4042); -- DPRINTK("reg4042 = 0x%04x\n", reg4042); -- sitre = (reg4042 & 0x4000) ? 1 : 0; -- pci_read_config_byte(dev, 0x48, ®48); -- pci_read_config_word(dev, 0x4a, ®4a); -- pci_read_config_byte(dev, 0x54, ®54); -- pci_read_config_byte(dev, 0x55, ®55); -- -- switch(speed) { -- case XFER_UDMA_4: -- case XFER_UDMA_2: u_speed = 2 << (drive_dn * 4); break; -- case XFER_UDMA_6: -- case XFER_UDMA_5: -- case XFER_UDMA_3: -- case XFER_UDMA_1: u_speed = 1 << (drive_dn * 4); break; -- case XFER_UDMA_0: u_speed = 0 << (drive_dn * 4); break; -- case XFER_MW_DMA_2: -- case XFER_MW_DMA_1: break; -- default: -- BUG(); -- return; -- } -+ u8 master_port = ap->hard_port_no ? 0x42 : 0x40; -+ u16 master_data; -+ u8 speed = adev->dma_mode; -+ int devid = adev->devno + 2 * ap->hard_port_no; -+ u8 udma_enable; -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; - -+ pci_read_config_word(dev, master_port, &master_data); -+ pci_read_config_byte(dev, 0x48, &udma_enable); -+ - 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); -+ unsigned int udma = adev->dma_mode - XFER_UDMA_0; -+ u16 udma_timing; -+ u32 ideconf; -+ int u_clock, u_speed; -+ -+ /* -+ * UDMA is handled by a combination of clock switching and -+ * selection of dividers -+ * -+ * Handy rule: Odd modes are UDMATIMx 01, even are 02 -+ * except UDMA0 which is 00 -+ */ -+ u_speed = min(2 - (udma & 1), udma); -+ if (udma == 5) -+ u_clock = 0x1000; /* 100Mhz */ -+ else if (udma > 2) -+ u_clock = 1; /* 66Mhz */ -+ else -+ u_clock = 0; /* 33Mhz */ -+ -+ udma_enable |= (1 << devid); -+ -+ /* Load the CT/RP selection */ -+ pci_read_config_word(dev, 0x4A, &udma_timing); -+ udma_timing &= ~(3 << (4 * devid)); -+ udma_timing |= u_speed << (4 * devid); -+ pci_write_config_word(dev, 0x4A, udma_timing); -+ -+ if(isich) { -+ /* Select a 33/66/100Mhz clock */ -+ pci_read_config_dword(dev, 0x54, &ideconf); -+ ideconf &= ~(0x1001 << devid); -+ ideconf |= u_clock << devid; -+ /* For ICH or later we should set bit 10 for better -+ performance (WR_PingPong_En) */ -+ pci_write_config_dword(dev, 0x54, ideconf); - } -- 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 { -- 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); -+ /* -+ * MWDMA is driven by the PIO timings. We must also enable -+ * IORDY unconditionally along with TIME1. PPE has already -+ * been set when the PIO timing was set. -+ */ -+ unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0; -+ unsigned int control; -+ u8 slave_data; -+ const unsigned int needed_pio[3] = { -+ XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 -+ }; -+ int pio = needed_pio[mwdma] - XFER_PIO_0; -+ -+ control = 3; /* IORDY|TIME1 */ -+ -+ /* If the drive MWDMA is faster than it can do PIO then -+ we must force PIO into PIO0 */ -+ -+ if (adev->pio_mode < needed_pio[mwdma]) -+ /* Enable DMA timing only */ -+ control |= 8; /* PIO cycles in PIO0 */ -+ -+ if (adev->devno) { /* Slave */ -+ master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */ -+ master_data |= control << 4; -+ pci_read_config_byte(dev, 0x44, &slave_data); -+ slave_data &= (0x0F + 0xE1 * ap->hard_port_no); -+ /* Load the matching timing */ -+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->hard_port_no ? 4 : 0); -+ pci_write_config_byte(dev, 0x44, slave_data); -+ } else { /* Master */ -+ master_data &= 0xCCF4; /* Mask out IORDY|TIME1|DMAONLY -+ and master timing bits */ -+ master_data |= control; -+ master_data |= -+ (timings[pio][0] << 12) | -+ (timings[pio][1] << 8); -+ } -+ udma_enable &= ~(1 << devid); -+ pci_write_config_word(dev, master_port, master_data); - } -+ /* Don't scribble on 0x48 if the controller does not support UDMA */ -+ if(ap->udma_mask) -+ pci_write_config_byte(dev, 0x48, udma_enable); -+} -+ -+/** -+ * piix_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: um -+ * -+ * Set MW/UDMA mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ do_pata_set_dmamode(ap, adev, 0); -+} -+ -+/** -+ * ich_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: um -+ * -+ * Set MW/UDMA mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ do_pata_set_dmamode(ap, adev, 1); - } - - #define AHCI_PCI_BAR 5 -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/Kconfig linux-2.6.16-rc2/drivers/scsi/Kconfig ---- linux.vanilla-2.6.16-rc2/drivers/scsi/Kconfig 2006-02-06 12:21:35.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/Kconfig 2006-02-07 13:48:49.000000000 +0000 -@@ -599,6 +599,289 @@ - depends on IDE=y && !BLK_DEV_IDE_SATA && (SCSI_SATA_AHCI || SCSI_ATA_PIIX) - default y - -+config SCSI_PATA_ALI -+ tristate "ALi PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the ALi ATA interfaces -+ found on the many ALi chipsets. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_AMD -+ tristate "AMD/NVidia PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the AMD and NVidia PATA -+ interfaces found on the chipsets for Athlon/Athlon64. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_ARTOP -+ tristate "ARTOP 6210/6260 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for ARTOP PATA controllers. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_ATIIXP -+ tristate "ATI PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the ATI ATA interfaces -+ found on the many ATI chipsets. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_CMD64X -+ tristate "CMD64x PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the CMD64x series chips -+ except for the CMD640. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_CS5520 -+ tristate "CS5510/5520 PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the Cyrix 5510/5520 -+ companion chip used with the MediaGX/Geode processor family. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_CS5530 -+ tristate "CS5530 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the Cyrix/NatSemi/AMD CS5530 -+ companion chip used with the MediaGX/Geode processor family. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_CS5535 -+ tristate "CS5535 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && X86 && !X86_64 && EXPERIMENTAL -+ help -+ This option enables support for the NatSemi/AMD CS5535 -+ companion chip used with the Geode processor family. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_CYPRESS -+ tristate "Cypress CY82C693 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the Cypress/Contaq CY82C693 -+ chipset found in some Alpha systems -+ -+ If unsure, say N. -+ -+config SCSI_PATA_EFAR -+ tristate "EFAR SLC90E66 support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the EFAR SLC90E66 -+ IDE controller found on some older machines. -+ -+ If unsure, say N. -+ -+config SCSI_ATA_GENERIC -+ tristate "Generic PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for generic BIOS configured -+ PATA controllers via the new ATA layer -+ -+ If unsure, say N. -+ -+config SCSI_PATA_HPT37X -+ tristate "HPT 370/370A/371/372/374/302 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the majority of the later HPT -+ PATA controllers via the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_HPT3X2N -+ tristate "HPT 372N/302N PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the N variant HPT PATA -+ controllers via the new ATA layer -+ -+ If unsure, say N. -+ -+config SCSI_PATA_HPT3X3 -+ tristate "HPT 343/363 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the HPT 343/363 -+ PATA controllers via the new ATA layer -+ -+ If unsure, say N. -+ -+config SCSI_PATA_ISAPNP -+ tristate "ISA Plug and Play PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && EXPERIMENTAL -+ help -+ This option enables support for ISA plug & play ATA -+ controllers such as those found on old soundcards. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_IT8172 -+ tristate "IT8172 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the ITE 8172 PATA controller -+ via the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_IT821X -+ tristate "IT821x PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the ITE 8211 and 8212 -+ PATA controllers via the new ATA layer, including RAID -+ mode. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_LEGACY -+ tristate "Legacy ISA PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for ISA bus legacy PATA -+ interfaces on ide2-5 and allows them to be accessed via -+ the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_MPIIX -+ tristate "Intel PATA MPIIX support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for MPIIX PATA support. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_NETCELL -+ tristate "NETCELL Revolution RAID support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the Netcell Revolution RAID -+ PATA controller. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_OLDPIIX -+ tristate "Intel PATA old PIIX support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for old(?) PIIX PATA support. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_OPTI -+ tristate "OPTI621/6215 PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables full PIO support for the early Opti ATA -+ controllers found on some old motherboards. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_PCMCIA -+ tristate "PCMCIA PATA support (Raving Lunatic)" -+ depends on SCSI_SATA -+ help -+ This option enables support for PCMCIA ATA interfaces, including -+ compact flash card adapters via the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_QDI -+ tristate "QDI VLB PATA support" -+ depends on SCSI_SATA -+ help -+ Support for QDI 6500 and 6580 PATA controllers on VESA local bus. -+ -+config SCSI_PATA_RZ1000 -+ tristate "PC Tech RZ1000 PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables basic support for the PC Tech RZ1000/1 -+ PATA controllers via the new ATA layer -+ -+ If unsure, say N. -+ -+config SCSI_PATA_SC1200 -+ tristate "SC1200 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the NatSemi/AMD SC1200 SoC -+ companion chip used with the Geode processor family. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_SERVERWORKS -+ tristate "SERVERWORKS OSB4/CSB5/CSB6 PATA support (Experimental)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the Serverworks OSB4/CSB5 and -+ CSB6 IDE controllers, via the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_SIL680 -+ tristate "CMD / Silicon Image 680 PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for CMD / Silicon Image 680 PATA. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_SIS -+ tristate "SiS PATA support (Experimental)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for SiS PATA controllers -+ -+ If unsure, say N. -+ -+config SCSI_PATA_TRIFLEX -+ tristate "Compaq Triflex PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ Enable support for the Compaq 'Triflex' IDE controller as found -+ on many Compaq Pentium-Pro systems, via the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_VIA -+ tristate "VIA PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the VIA PATA interfaces -+ found on the many VIA chipsets. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_WINBOND -+ tristate "Winbond SL82C105 PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for SL82C105 PATA devices found in the -+ Netwinder and some other systems -+ -+ If unsure, say N. -+ -+ - config SCSI_BUSLOGIC - tristate "BusLogic SCSI support" - depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/libata-core.c linux-2.6.16-rc2/drivers/scsi/libata-core.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/libata-core.c 2006-02-06 12:21:35.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/libata-core.c 2006-02-07 11:23:41.765951784 +0000 -@@ -68,9 +68,10 @@ - static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); - 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(const struct ata_port *ap, int shift); -+static unsigned int ata_get_mode_mask(const struct ata_port *ap, struct ata_device *adev, int shift); - static int fgb(u32 bitmap); - static int ata_choose_xfer_mode(const struct ata_port *ap, -+ struct ata_device *adev, - u8 *xfer_mode_out, - unsigned int *xfer_shift_out); - static void __ata_qc_complete(struct ata_queued_cmd *qc); -@@ -614,7 +615,7 @@ - } else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) { - /* Unable to use DMA due to host limitation */ - tf->protocol = ATA_PROT_PIO; -- index = dev->multi_count ? 0 : 4; -+ index = dev->multi_count ? 0 : 8; - } else { - tf->protocol = ATA_PROT_DMA; - index = 16; -@@ -1205,6 +1206,48 @@ - return 0; - } - -+static void ata_dev_check_hpa(struct ata_port *ap, struct ata_device *dev) -+{ -+ struct ata_taskfile tf; -+ unsigned long long true_size; -+ unsigned int err_mask; -+ -+ if (!ata_id_has_hpa(dev->id) || !ata_id_hpa_enabled(dev->id)) -+ return; -+ -+ /* Issue a query for HPA */ -+ ata_dev_select(ap, dev->devno, 1, 1); -+ ata_tf_init(ap, &tf, dev->devno); -+ -+ if (dev->flags & ATA_DFLAG_LBA48) { -+ tf.command = ATA_CMD_READ_NATIVE_MAX_EXT; -+ tf.device |= 0x40; -+ err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); -+ if (err_mask) -+ return; -+ /* Ok HPA is live */ -+ true_size = (tf.hob_lbah << 16) | (tf.hob_lbam << 8) | (tf.hob_lbal); -+ true_size <<= 24; -+ true_size |= (tf.lbah << 16) | (tf.lbam << 8) | tf.lbal; -+ } else { -+ tf.command = ATA_CMD_READ_NATIVE_MAX; -+ tf.device |= 0x40; -+ err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); -+ if (err_mask) -+ return; -+ /* Ok HPA is live */ -+ true_size = ((tf.device & 0x0F) << 24) | -+ (tf.lbah << 16) | -+ (tf.lbam << 8) | -+ tf.lbal; -+ } -+ dev->flags |= ATA_DFLAG_HPA; -+ /* Should save the HPA value and expose it for dmraid then -+ remove the clipping */ -+ printk(KERN_INFO "HPA present: true size %lld sectors.\n", -+ true_size + 1); -+} -+ - /** - * ata_dev_identify - obtain IDENTIFY x DEVICE page - * @ap: port on which device we wish to probe resides -@@ -1328,7 +1371,7 @@ - - /* ATA-specific feature tests */ - if (dev->class == ATA_DEV_ATA) { -- if (!ata_id_is_ata(dev->id)) /* sanity check */ -+ if (!ata_id_is_ata(dev->id) && !ata_id_is_cfa(dev->id)) /* sanity check */ - goto err_out_nosup; - - /* get major version */ -@@ -1400,6 +1443,13 @@ - } - - ap->host->max_cmd_len = 16; -+ -+ /* -+ * See if we have the HPA misfeature on the drive -+ */ -+#if 0 /* TESTING */ -+ ata_dev_check_hpa(ap, dev); -+#endif - } - - /* ATAPI-specific feature tests */ -@@ -1497,7 +1547,11 @@ - if ((!found) || (ap->flags & ATA_FLAG_PORT_DISABLED)) - goto err_out_disable; - -- ata_set_mode(ap); -+ if(ap->ops->set_mode) -+ ap->ops->set_mode(ap); -+ else -+ ata_set_mode(ap); -+ - if (ap->flags & ATA_FLAG_PORT_DISABLED) - goto err_out_disable; - -@@ -1824,16 +1878,19 @@ - ap->id, dev->devno, xfer_mode_str[idx]); - } - --static int ata_host_set_pio(struct ata_port *ap) -+static int ata_host_set_pio(struct ata_port *ap, struct ata_device *adev) - { - unsigned int mask; -- int x, i; -+ int x; - u8 base, xfer_mode; - -- mask = ata_get_mode_mask(ap, ATA_SHIFT_PIO); -+ if (!ata_dev_present(adev)) -+ return 0; -+ -+ mask = ata_get_mode_mask(ap, adev, ATA_SHIFT_PIO); - x = fgb(mask); - if (x < 0) { -- printk(KERN_WARNING "ata%u: no PIO support\n", ap->id); -+ printk(KERN_WARNING "ata%u: no PIO support for device %d.\n", ap->id, adev->devno); - return -1; - } - -@@ -1843,34 +1900,24 @@ - 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); -- } -- } -+ adev->pio_mode = xfer_mode; -+ adev->xfer_mode = xfer_mode; -+ adev->xfer_shift = ATA_SHIFT_PIO; -+ if (ap->ops->set_piomode) -+ ap->ops->set_piomode(ap, adev); - - return 0; - } - --static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode, -- unsigned int xfer_shift) -+static void ata_host_set_dma(struct ata_port *ap, struct ata_device *adev, -+ 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); -- } -+ if (ata_dev_present(adev)) { -+ adev->dma_mode = xfer_mode; -+ adev->xfer_mode = xfer_mode; -+ adev->xfer_shift = xfer_shift; -+ if (ap->ops->set_dmamode) -+ ap->ops->set_dmamode(ap, adev); - } - } - -@@ -1886,32 +1933,64 @@ - */ - static void ata_set_mode(struct ata_port *ap) - { -- unsigned int xfer_shift; -- u8 xfer_mode; -+ unsigned int xfer_shift[ATA_MAX_DEVICES]; -+ u8 xfer_mode[ATA_MAX_DEVICES]; - int rc; -+ int i; -+ int used_dma = 0; /* Track if DMA was used for this setup */ - -- /* step 1: always set host PIO timings */ -- rc = ata_host_set_pio(ap); -- if (rc) -- goto err_out; -+ /* We need to set timings individually for each device */ - -- /* 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; -+ /* Compute the timings first so that when we ask the device to do -+ speed configuration it can see all the intended device state in -+ full */ -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *adev = &ap->device[i]; -+ /* Choose the best data xfer mode */ -+ xfer_mode[i] = xfer_shift[i] = 0; -+ rc = ata_choose_xfer_mode(ap, adev, &xfer_mode[i], &xfer_shift[i]); -+ if (rc) -+ goto err_out; -+ -+ } -+ -+ /* Now set the mode tables we have computed */ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *adev = &ap->device[i]; -+ /* step 1: always set host PIO timings */ -+ rc = ata_host_set_pio(ap, adev); -+ if (rc) -+ goto err_out; -+ -+ /* step 2: if that xfer mode isn't PIO, set host DMA timings */ -+ if (xfer_shift[i] != ATA_SHIFT_PIO) { -+ ata_host_set_dma(ap, adev, xfer_mode[i], xfer_shift[i]); -+ used_dma = 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]); -+ /* In some cases the DMA mode will cause the driver to -+ update the pio mode to match chip limits. */ -+ -+ /* step 3: update devices' xfer mode */ -+ ata_dev_set_mode(ap, adev); -+ } - - if (ap->flags & ATA_FLAG_PORT_DISABLED) - return; - -+ /* -+ * Record simplex status. If we selected DMA then the other -+ * host channels are not permitted to do so. -+ */ -+ -+ if (used_dma && (ap->host_set->host_set_flags & ATA_HOST_SIMPLEX)) -+ ap->host_set->simplex_claimed = 1; -+ -+ /* -+ * Chip specific finalisation -+ */ -+ - if (ap->ops->post_set_mode) - ap->ops->post_set_mode(ap); - -@@ -2256,76 +2335,57 @@ - return 0; - } - --static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift) -+static unsigned int ata_get_mode_mask(const struct ata_port *ap, struct ata_device *adev, int shift) - { -- const struct ata_device *master, *slave; - unsigned int mask; -+ struct ata_host_set *hs = ap->host_set; -+ -+ if (!ata_dev_present(adev)) -+ return 0xFF; /* Drive isn't limiting anything */ -+ -+ if (shift == ATA_SHIFT_PIO) { -+ u16 tmp_mode = ata_pio_modes(adev); -+ mask = ap->pio_mask; -+ mask &= tmp_mode; -+ } - -- master = &ap->device[0]; -- slave = &ap->device[1]; -+ /* -+ * Enforce simplex rules if host is simplex -+ */ - -- assert (ata_dev_present(master) || ata_dev_present(slave)); -+ if (hs->host_set_flags & ATA_HOST_SIMPLEX) { -+ if (hs->simplex_claimed) { -+ if (shift != ATA_SHIFT_PIO) -+ return 0; -+ } -+ } - - if (shift == ATA_SHIFT_UDMA) { - mask = ap->udma_mask; -- if (ata_dev_present(master)) { -- mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff); -- if (ata_dma_blacklisted(master)) { -- mask = 0; -- ata_pr_blacklisted(ap, master); -- } -- } -- if (ata_dev_present(slave)) { -- mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff); -- if (ata_dma_blacklisted(slave)) { -- mask = 0; -- ata_pr_blacklisted(ap, slave); -- } -+ mask &= (adev->id[ATA_ID_UDMA_MODES] & 0xff); -+ if (ata_dma_blacklisted(adev)) { -+ mask = 0; -+ ata_pr_blacklisted(ap, adev); - } - } - 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_dma_blacklisted(master)) { -- mask = 0; -- ata_pr_blacklisted(ap, master); -- } -- } -- if (ata_dev_present(slave)) { -- mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07); -- if (ata_dma_blacklisted(slave)) { -- mask = 0; -- ata_pr_blacklisted(ap, slave); -- } -- } -- } -- 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; -+ mask &= (adev->id[ATA_ID_MWDMA_MODES] & 0x07); -+ if (ata_dma_blacklisted(adev)) { -+ mask = 0; -+ ata_pr_blacklisted(ap, adev); - } -- } -- else { -+ } else if (shift != ATA_SHIFT_PIO) { - mask = 0xffffffff; /* shut up compiler warning */ - BUG(); - } - -+ /* -+ * Allow the controller to see the proposed mode and -+ * device data to do any custom filtering rules. -+ */ -+ if(ap->ops->mode_filter) -+ mask = ap->ops->mode_filter(ap, adev, mask, shift); - return mask; - } - -@@ -2345,6 +2405,7 @@ - /** - * ata_choose_xfer_mode - attempt to find best transfer mode - * @ap: Port for which an xfer mode will be selected -+ * @adev: ATA device for which xfer mode is being selected - * @xfer_mode_out: (output) SET FEATURES - XFER MODE code - * @xfer_shift_out: (output) bit shift that selects this mode - * -@@ -2359,6 +2420,7 @@ - */ - - static int ata_choose_xfer_mode(const struct ata_port *ap, -+ struct ata_device *adev, - u8 *xfer_mode_out, - unsigned int *xfer_shift_out) - { -@@ -2367,7 +2429,7 @@ - - for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) { - shift = xfer_mode_classes[i].shift; -- mask = ata_get_mode_mask(ap, shift); -+ mask = ata_get_mode_mask(ap, adev, shift); - - x = fgb(mask); - if (x >= 0) { -@@ -3010,7 +3072,7 @@ - * Inherited from caller. - */ - --static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, -+void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, - unsigned int buflen, int write_data) - { - unsigned int i; -@@ -3055,11 +3117,11 @@ - * Inherited from caller. - */ - --static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf, -+void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf, - unsigned int buflen, int write_data) - { - unsigned int words = buflen >> 1; -- -+ - /* Transfer multiple of 2 bytes */ - if (write_data) - outsw(ap->ioaddr.data_addr, buf, words); -@@ -3082,36 +3144,53 @@ - } - - /** -- * ata_data_xfer - Transfer data from/to the data register. -+ * ata_pio_data_xfer_noirq - Transfer data from/to the data register. - * @ap: port to read/write - * @buf: data buffer - * @buflen: buffer length - * @do_write: read/write - * -- * Transfer data from/to the device data register. -+ * Transfer data from/to the device data register. This variant -+ * ensures local IRQs do not interrupt the data stream and this -+ * is needed for some controllers. - * - * LOCKING: - * Inherited from caller. - */ - --static void ata_data_xfer(struct ata_port *ap, unsigned char *buf, -+void ata_pio_data_xfer_noirq(struct ata_port *ap, unsigned char *buf, - unsigned int buflen, int do_write) - { - /* Make the crap hardware pay the costs not the good stuff */ -- if (unlikely(ap->flags & ATA_FLAG_IRQ_MASK)) { -- unsigned long flags; -- local_irq_save(flags); -- 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); -- local_irq_restore(flags); -- } else { -- 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); -- } -+ unsigned long flags; -+ local_irq_save(flags); -+ ata_pio_data_xfer(ap, buf, buflen, do_write); -+ local_irq_restore(flags); -+} -+ -+/** -+ * ata_mmio_data_xfer_noirq - Transfer data from/to the data register. -+ * @ap: address to read/write -+ * @buf: data buffer -+ * @buflen: buffer length -+ * @do_write: read/write -+ * -+ * Transfer data from/to the device data register. This variant -+ * ensures local IRQs do not interrupt the data stream and this -+ * is needed for some controllers. -+ * -+ * LOCKING: -+ * Inherited from caller. -+ */ -+ -+void ata_mmio_data_xfer_noirq(struct ata_port *ap, unsigned char *buf, -+ unsigned int buflen, int do_write) -+{ -+ /* Make the crap hardware pay the costs not the good stuff */ -+ unsigned long flags; -+ local_irq_save(flags); -+ ata_mmio_data_xfer(ap, buf, buflen, do_write); -+ local_irq_restore(flags); - } - - /** -@@ -3157,7 +3236,7 @@ - - /* do the actual data transfer */ - do_write = (qc->tf.flags & ATA_TFLAG_WRITE); -- ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write); -+ ap->ops->data_xfer(ap, buf, ATA_SECT_SIZE, do_write); - - kunmap(page); - } -@@ -3204,7 +3283,7 @@ - ap->id, bytes); - - for (i = 0; i < words; i++) -- ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write); -+ ap->ops->data_xfer(ap, (unsigned char*)pad_buf, 2, do_write); - - ap->hsm_task_state = HSM_ST_LAST; - return; -@@ -3239,7 +3318,7 @@ - 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); -+ ap->ops->data_xfer(ap, buf, count, do_write); - - kunmap(page); - -@@ -3947,14 +4026,15 @@ - - void ata_bmdma_irq_clear(struct ata_port *ap) - { -- if (ap->flags & ATA_FLAG_MMIO) { -- void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS; -- writeb(readb(mmio), mmio); -- } else { -- unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS; -- outb(inb(addr), addr); -- } -- -+ if (ap->ioaddr.bmdma_addr) { -+ if (ap->flags & ATA_FLAG_MMIO) { -+ void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS; -+ writeb(readb(mmio), mmio); -+ } else { -+ unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS; -+ outb(inb(addr), addr); -+ } -+ } - } - - -@@ -4193,12 +4273,12 @@ - */ - spin_lock_irqsave(&ap->host_set->lock, flags); - ap->flags &= ~ATA_FLAG_NOINTR; -- ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); -+ ap->ops->data_xfer(ap, qc->cdb, ap->cdb_len, 1); - if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) - ap->ops->bmdma_start(qc); /* initiate bmdma */ - spin_unlock_irqrestore(&ap->host_set->lock, flags); - } else { -- ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); -+ ap->ops->data_xfer(ap, qc->cdb, ap->cdb_len, 1); - - /* PIO commands are handled by polling */ - ap->hsm_task_state = HSM_ST; -@@ -4504,7 +4584,7 @@ - * Number of ports registered. Zero on error (no ports registered). - */ - --int ata_device_add(const struct ata_probe_ent *ent) -+int ata_device_add(struct ata_probe_ent *ent) - { - unsigned int count = 0, i; - struct device *dev = ent->dev; -@@ -4524,6 +4604,9 @@ - host_set->mmio_base = ent->mmio_base; - host_set->private_data = ent->private_data; - host_set->ops = ent->port_ops; -+ host_set->host_set_flags = ent->host_set_flags; -+ -+ ent->host_set = host_set; - - /* register each port bound to this device */ - for (i = 0; i < ent->n_ports; i++) { -@@ -4535,6 +4618,14 @@ - goto err_out; - - host_set->ports[i] = ap; -+ -+ /* Tidy up if we have no bus master base -+ Not sure this is the right spot to do it */ -+ if (ap->ioaddr.bmdma_addr == 0) { -+ ap->udma_mask = 0; -+ ap->mwdma_mask = 0; -+ } -+ - xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) | - (ap->mwdma_mask << ATA_SHIFT_MWDMA) | - (ap->pio_mask << ATA_SHIFT_PIO); -@@ -4551,6 +4642,7 @@ - ent->irq); - - ata_chk_status(ap); -+ /* This last call probably should be conditional on bmdma */ - host_set->ops->irq_clear(ap); - count++; - } -@@ -4604,7 +4696,8 @@ - ata_scsi_scan_host(ap); - } - -- dev_set_drvdata(dev, host_set); -+ if(dev) -+ dev_set_drvdata(dev, host_set); - - VPRINTK("EXIT, returning %u\n", ent->n_ports); - return ent->n_ports; /* success */ -@@ -4778,6 +4871,7 @@ - { - struct ata_probe_ent *probe_ent = - ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); -+ unsigned long bmdma; - int p = 0; - - if (!probe_ent) -@@ -4792,7 +4886,13 @@ - probe_ent->port[p].altstatus_addr = - probe_ent->port[p].ctl_addr = - pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; -- probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4); -+ bmdma = pci_resource_start(pdev, 4); -+ -+ if (bmdma) { -+ if (inb(bmdma + 2) & 0x80) -+ probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; -+ probe_ent->port[p].bmdma_addr = bmdma; -+ } - ata_std_ports(&probe_ent->port[p]); - p++; - } -@@ -4802,7 +4902,14 @@ - probe_ent->port[p].altstatus_addr = - probe_ent->port[p].ctl_addr = - pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; -- probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8; -+ bmdma = pci_resource_start(pdev, 4); -+ -+ if (bmdma) { -+ bmdma += 8; -+ if(inb(bmdma + 2) & 0x80) -+ probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; -+ probe_ent->port[p].bmdma_addr = bmdma; -+ } - ata_std_ports(&probe_ent->port[p]); - p++; - } -@@ -4814,6 +4921,7 @@ - static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num) - { - struct ata_probe_ent *probe_ent; -+ unsigned long bmdma; - - probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); - if (!probe_ent) -@@ -4839,7 +4947,13 @@ - probe_ent->port[0].ctl_addr = 0x376; - break; - } -- probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num; -+ bmdma = pci_resource_start(pdev, 4); -+ if(bmdma != 0) { -+ bmdma += 8 * port_num; -+ probe_ent->port[0].bmdma_addr = bmdma; -+ if (inb(bmdma + 2) & 0x80) -+ probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; -+ } - ata_std_ports(&probe_ent->port[0]); - return probe_ent; - } -@@ -5080,6 +5194,33 @@ - pci_set_master(pdev); - return 0; - } -+ -+/** -+ * ata_pci_clear_simplex - attempt to kick device out of simplex -+ * @pdev: PCI device -+ * -+ * Some PCI ATA devices report simplex mode but in fact can be told to -+ * enter non simplex mode. This implements the neccessary logic to -+ * perform the task on such devices. Calling it on other devices will -+ * have -undefined- behaviour. -+ */ -+ -+int ata_pci_clear_simplex(struct pci_dev *pdev) -+{ -+ unsigned long bmdma = pci_resource_start(pdev, 4); -+ u8 simplex; -+ -+ if (bmdma == 0) -+ return -ENOENT; -+ -+ simplex = inb(bmdma + 0x02); -+ outb(simplex & 0x60, bmdma + 0x02); -+ simplex = inb(bmdma + 0x02); -+ if (simplex & 0x80) -+ return -EOPNOTSUPP; -+ return 0; -+} -+ - #endif /* CONFIG_PCI */ - - -@@ -5157,6 +5298,10 @@ - EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear); - EXPORT_SYMBOL_GPL(ata_bmdma_status); - EXPORT_SYMBOL_GPL(ata_bmdma_stop); -+EXPORT_SYMBOL_GPL(ata_mmio_data_xfer); -+EXPORT_SYMBOL_GPL(ata_pio_data_xfer); -+EXPORT_SYMBOL_GPL(ata_mmio_data_xfer_noirq); -+EXPORT_SYMBOL_GPL(ata_pio_data_xfer_noirq); - EXPORT_SYMBOL_GPL(ata_port_probe); - EXPORT_SYMBOL_GPL(sata_phy_reset); - EXPORT_SYMBOL_GPL(__sata_phy_reset); -@@ -5186,6 +5331,8 @@ - EXPORT_SYMBOL_GPL(ata_pci_remove_one); - EXPORT_SYMBOL_GPL(ata_pci_device_suspend); - EXPORT_SYMBOL_GPL(ata_pci_device_resume); -+EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); -+ - #endif /* CONFIG_PCI */ - - EXPORT_SYMBOL_GPL(ata_device_suspend); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/Makefile linux-2.6.16-rc2/drivers/scsi/Makefile ---- linux.vanilla-2.6.16-rc2/drivers/scsi/Makefile 2006-02-06 12:21:35.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/Makefile 2006-02-07 13:49:19.944546720 +0000 -@@ -139,6 +139,39 @@ - obj-$(CONFIG_SCSI_SATA_MV) += libata.o sata_mv.o - obj-$(CONFIG_SCSI_PDC_ADMA) += libata.o pdc_adma.o - -+obj-$(CONFIG_SCSI_PATA_ALI) += libata.o pata_ali.o -+obj-$(CONFIG_SCSI_PATA_AMD) += libata.o pata_amd.o -+obj-$(CONFIG_SCSI_PATA_ARTOP) += libata.o pata_artop.o -+obj-$(CONFIG_SCSI_PATA_ATIIXP) += libata.o pata_atiixp.o -+obj-$(CONFIG_SCSI_PATA_CMD64X) += libata.o pata_cmd64x.o -+obj-$(CONFIG_SCSI_PATA_CS5520) += libata.o pata_cs5520.o -+obj-$(CONFIG_SCSI_PATA_CS5530) += libata.o pata_cs5530.o -+obj-$(CONFIG_SCSI_PATA_CS5535) += libata.o pata_cs5535.o -+obj-$(CONFIG_SCSI_PATA_CYPRESS) += libata.o pata_cypress.o -+obj-$(CONFIG_SCSI_PATA_EFAR) += libata.o pata_efar.o -+obj-$(CONFIG_SCSI_PATA_ISAPNP) += libata.o pata_isapnp.o -+obj-$(CONFIG_SCSI_PATA_HPT37X) += libata.o pata_hpt37x.o -+obj-$(CONFIG_SCSI_PATA_HPT3X2N) += libata.o pata_hpt3x2n.o -+obj-$(CONFIG_SCSI_PATA_HPT3X3) += libata.o pata_hpt34x.o -+obj-$(CONFIG_SCSI_PATA_IT8172) += libata.o pata_it8172.o -+obj-$(CONFIG_SCSI_PATA_IT821X) += libata.o pata_it821x.o -+obj-$(CONFIG_SCSI_PATA_MPIIX) += libata.o pata_mpiix.o -+obj-$(CONFIG_SCSI_PATA_NETCELL) += libata.o pata_netcell.o -+obj-$(CONFIG_SCSI_PATA_OLDPIIX) += libata.o pata_oldpiix.o -+obj-$(CONFIG_SCSI_PATA_OPTI) += libata.o pata_opti.o -+obj-$(CONFIG_SCSI_PATA_PCMCIA) += libata.o pata_pcmcia.o -+obj-$(CONFIG_SCSI_PATA_QDI) += libata.o pata_qdi.o -+obj-$(CONFIG_SCSI_PATA_RZ1000) += libata.o pata_rz1000.o -+obj-$(CONFIG_SCSI_PATA_SERVERWORKS) += libata.o pata_serverworks.o -+obj-$(CONFIG_SCSI_PATA_SC1200) += libata.o pata_sc1200.o -+obj-$(CONFIG_SCSI_PATA_SIL680) += libata.o pata_sil680.o -+obj-$(CONFIG_SCSI_PATA_SIS) += libata.o pata_sis.o -+obj-$(CONFIG_SCSI_PATA_TRIFLEX) += libata.o pata_triflex.o -+obj-$(CONFIG_SCSI_PATA_VIA) += libata.o pata_via.o -+obj-$(CONFIG_SCSI_PATA_WINBOND) += libata.o pata_sl82c105.o -+obj-$(CONFIG_SCSI_ATA_GENERIC) += libata.o ata_generic.o -+obj-$(CONFIG_SCSI_PATA_LEGACY) += libata.o pata_legacy.o -+ - obj-$(CONFIG_ARM) += arm/ - - obj-$(CONFIG_CHR_DEV_ST) += st.o -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_ali.c linux-2.6.16-rc2/drivers/scsi/pata_ali.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_ali.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_ali.c 2006-02-07 13:41:31.570750360 +0000 -@@ -0,0 +1,602 @@ -+/* -+ * ata-ali.c - ALI 15x3 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * TODO -+ * MWDMA timings -+ * -+ * based in part upon -+ * linux/drivers/ide/pci/alim15x3.c Version 0.17 2003/01/02 -+ * -+ * Copyright (C) 1998-2000 Michel Aubry, Maintainer -+ * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer -+ * Copyright (C) 1999-2000 CJ, cjtsai@ali.com.tw, Maintainer -+ * -+ * Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org) -+ * May be copied or modified under the terms of the GNU General Public License -+ * Copyright (C) 2002 Alan Cox <alan@redhat.com> -+ * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> -+ * -+ * Documentation -+ * Chipset documentation available under NDA only -+ * -+ * TODO -+ * Cannot have ATAPI on both master & slave for rev < c2 but -+ * otherwise should do atapi DMA. -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "ali" -+#define DRV_VERSION "0.1.1" -+ -+/** -+ * ali_c2_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection for C2 and later revisions -+ */ -+ -+static int ali_c2_cable_detect(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 ata66; -+ -+ /* Certain laptops use short but suitable cables and don't -+ implement the detect logic */ -+ -+ /* Fujitsu P2000 */ -+ if(pdev->subsystem_vendor == 0x10CF && pdev->subsystem_device == 0x10AF) -+ return ATA_CBL_PATA80; -+ -+ /* Host view cable detect 0x4A bit 0 primary bit 1 secondary -+ Bit set for 40 pin */ -+ pci_read_config_byte(pdev, 0x4A, &ata66); -+ if(ata66 & (1 << ap->hard_port_no)) -+ return ATA_CBL_PATA40; -+ else -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * ali_early_phy_reset - reset for eary chip -+ * @ap: ATA port -+ * -+ * Handle the reset callback for the later chips with cable detect -+ */ -+ -+static void ali_c2_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ali_c2_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * ali_early_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection for older chipsets. This turns out to be -+ * rather easy to implement -+ */ -+ -+static int ali_early_cable_detect(struct ata_port *ap) { -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * ali_early_phy_reset - reset for eary chip -+ * @ap: ATA port -+ * -+ * Handle the reset callback for the early (pre cable detect) chips. -+ */ -+ -+static void ali_early_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ali_early_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * ali_20_filter - filter for earlier ALI DMA -+ * @ap: ALi ATA port -+ * @adev: attached device -+ * -+ * Ensure that we do not do DMA on CD devices. We may be able to -+ * fix that later on. Also ensure we do not do UDMA on WDC drives -+ */ -+ -+static unsigned int ali_20_filter(const struct ata_port *ap, struct ata_device *adev, unsigned int mask, int shift) -+{ -+ char model_num[40]; -+ /* No DMA on CD for now */ -+ if(adev->class != ATA_DEV_ATA && shift != ATA_SHIFT_PIO) -+ return 0; -+ -+ if(shift != ATA_SHIFT_UDMA) -+ return mask; -+ -+ ata_dev_id_string(adev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num)); -+ if(strstr(model_num, "WDC")) -+ return 0; -+ return mask; -+} -+ -+/** -+ * ali_fifo_control - FIFO manager -+ * @ap: ALi channel to control -+ * @adev: device for FIFO control -+ * @on: 0 for off 1 for on -+ * -+ * Enable or disable the FIFO on a given device. Because of the way the -+ * ALi FIFO works it provides a boost on ATA disk but can be confused by -+ * ATAPI and we must therefore manage it. -+ */ -+ -+static void ali_fifo_control(struct ata_port *ap, struct ata_device *adev, int on) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int pio_fifo = 0x54 + ap->hard_port_no; -+ u8 fifo; -+ int shift = 4 * adev->devno; -+ -+ /* Bits 3:2 (7:6 for slave) control the PIO. 00 is off 01 -+ is on. The FIFO must not be used for ATAPI. We preserve -+ BIOS set thresholds */ -+ pci_read_config_byte(pdev, pio_fifo, &fifo); -+ fifo &= (0x0C << shift); -+ if(on) -+ fifo |= (0x04 << shift); -+ pci_write_config_byte(pdev, pio_fifo, fifo); -+} -+ -+/** -+ * ali_program_modes - load mode registers -+ * @ap: ALi channel to load -+ * @adev: Device the timing is for -+ * @cmd: Command timing -+ * @data: Data timing -+ * @udma: UDMA timing or zero for off -+ * -+ * Loads the timing registers for cmd/data and disable UDMA if -+ * udma is zero. If udma is set then load and enable the UDMA -+ * timing but do not touch the command/data timing. -+ */ -+ -+static void ali_program_modes(struct ata_port *ap, struct ata_device *adev, u8 cmd, u8 data, u8 ultra) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int cbt = 0x59 + 4 * ap->hard_port_no; -+ int drwt = 0x5A + 4 * ap->hard_port_no + adev->devno; -+ int udmat = 0x56 + ap->hard_port_no; -+ int shift = 4 * adev->devno; -+ u8 udma; -+ -+ if(ultra == 0) { -+ /* Load the command block timing register */ -+ pci_write_config_byte(pdev, cbt, cmd); -+ -+ /* Load the data transfer timing register */ -+ pci_write_config_byte(pdev, drwt, data); -+ } -+ -+ /* Set up the UDMA enable */ -+ pci_read_config_byte(pdev, udmat, &udma); -+ udma &= ~(0x0F << shift); -+ udma |= ultra << shift; -+ pci_write_config_byte(pdev, udmat, udma); -+ -+} -+ -+/** -+ * ali_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the ALi registers for PIO mode. FIXME: add timings for -+ * PIO5. -+ */ -+ -+static void ali_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct ata_device *pair = &ap->device[1-adev->devno]; -+ int pio = adev->pio_mode - XFER_PIO_0; -+ int cmdpio = pio; -+ -+ /* These values are from the BIOS programming guide */ -+ static u8 cmd_block_timing[5] = { 0x0A, 0x03, 0x01, 0x33, 0x31 }; -+ static u8 data_block_timing[5] = { 0x88, 0x58, 0x44, 0x33, 0x31 }; -+ -+ if(adev->class != ATA_DEV_ATA) -+ ali_fifo_control(ap, adev, 0); -+ -+ /* Command timing is shared, so pick the best we can use */ -+ if(ata_dev_present(pair)) -+ cmdpio = min(pair->pio_mode, adev->pio_mode) - XFER_PIO_0; -+ -+ ali_program_modes(ap, adev, cmd_block_timing[cmdpio], -+ data_block_timing[pio], 0); -+ -+ if(adev->class == ATA_DEV_ATA) -+ ali_fifo_control(ap, adev, 1); -+ -+} -+ -+/** -+ * ali_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * FIXME: MWDMA timings -+ */ -+ -+static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD }; -+ -+ if(adev->dma_mode >= XFER_UDMA_0) { -+ ali_program_modes(ap, adev, 0, 0, udma_timing[adev->dma_mode - XFER_UDMA_0]); -+ } else { -+ /* MWDMA is not yet supported */ -+ /* ali_program_modes(ap, adev, cmd, data, 0); */ -+ } -+} -+ -+/** -+ * ali_lock_sectors - Keep older devices to 255 sector mode -+ * @ap: ATA port -+ * @adev: Device -+ * -+ * Called during the bus probe for each device that is found. We use -+ * this call to lock the sector count of the device to 255 or less on -+ * older ALi controllers. If we didn't do this then large I/O's would -+ * require LBA48 commands which the older ALi requires are issued by -+ * slower PIO methods -+ */ -+ -+static void ali_lock_sectors(struct ata_port *ap, struct ata_device *adev) -+{ -+ adev->flags |= ATA_DFLAG_LOCK_SECTORS; -+} -+ -+static struct scsi_host_template ali_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, -+ /* Keep LBA28 counts so large I/O's don't turn LBA48 and PIO -+ with older controllers. Not locked so will grow on C5 or later */ -+ .max_sectors = 255, -+ .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, -+// .ordered_flush = 1, -+}; -+ -+/* -+ * Port operations for PIO only ALi -+ */ -+ -+static struct ata_port_operations ali_early_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = ali_set_piomode, -+ .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 = ali_early_phy_reset, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Port operations for DMA capable ALi without cable -+ * detect -+ */ -+static struct ata_port_operations ali_20_port_ops = { -+ .port_disable = ata_port_disable, -+ -+ .set_piomode = ali_set_piomode, -+ .set_dmamode = ali_set_dmamode, -+ .mode_filter = ali_20_filter, -+ -+ .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, -+ .dev_config = ali_lock_sectors, -+ -+ .phy_reset = ali_early_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Port operations for DMA capable ALi with cable detect -+ */ -+static struct ata_port_operations ali_c2_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = ali_set_piomode, -+ .set_dmamode = ali_set_dmamode, -+ .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, -+ .dev_config = ali_lock_sectors, -+ -+ .phy_reset = ali_c2_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Port operations for DMA capable ALi with cable detect and LBA48 -+ */ -+static struct ata_port_operations ali_c5_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = ali_set_piomode, -+ .set_dmamode = ali_set_dmamode, -+ .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 = ali_c2_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * ali_init_one - discovery callback -+ * @pdev: PCI device ID -+ * @id: PCI table info -+ * -+ * An ALi IDE interface has been discovered. Figure out what revision -+ * and perform configuration work before handing it to the ATA layer -+ */ -+ -+static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info_early = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .port_ops = &ali_early_port_ops -+ }; -+ /* Revision 0x20 added DMA */ -+ static struct ata_port_info info_20 = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &ali_20_port_ops -+ }; -+ /* Revision 0x20 with support logic added UDMA */ -+ static struct ata_port_info info_20_udma = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x07, /* UDMA33 */ -+ .port_ops = &ali_20_port_ops -+ }; -+ /* Revision 0xC2 adds UDMA66 */ -+ static struct ata_port_info info_c2 = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, -+ .port_ops = &ali_c2_port_ops -+ }; -+ /* Revision 0xC3 is UDMA100 */ -+ static struct ata_port_info info_c3 = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &ali_c2_port_ops -+ }; -+ /* Revision 0xC4 is UDMA133 */ -+ static struct ata_port_info info_c4 = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &ali_c2_port_ops -+ }; -+ /* Revision 0xC5 is UDMA133 with LBA48 DMA */ -+ static struct ata_port_info info_c5 = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &ali_c5_port_ops -+ }; -+ -+ static struct ata_port_info *port_info[2]; -+ u8 rev, tmp; -+ struct pci_dev *north, *isa_bridge; -+ -+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); -+ -+ /* -+ * The chipset revision selects the driver operations and -+ * mode data. -+ */ -+ -+ if(rev < 0x20) { -+ port_info[0] = port_info[1] = &info_early; -+ } else if (rev < 0xC2) { -+ /* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */ -+ pci_read_config_byte(pdev, 0x4B, &tmp); -+ /* Clear CD-ROM DMA write bit */ -+ tmp &= 0x7F; -+ pci_write_config_byte(pdev, 0x4B, tmp); -+ port_info[0] = port_info[1] = &info_20; -+ } else if (rev == 0xC2) { -+ port_info[0] = port_info[1] = &info_c2; -+ } else if (rev == 0xC3) { -+ port_info[0] = port_info[1] = &info_c3; -+ } else if (rev == 0xC4) { -+ port_info[0] = port_info[1] = &info_c4; -+ } else -+ port_info[0] = port_info[1] = &info_c5; -+ -+ if(rev >= 0xC2) { -+ /* Enable cable detection logic */ -+ pci_read_config_byte(pdev, 0x4B, &tmp); -+ pci_write_config_byte(pdev, 0x4B, tmp | 0x08); -+ } -+ -+ north = pci_get_slot(0, PCI_DEVFN(0,0)); -+ isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); -+ -+ if(north && north->vendor == PCI_VENDOR_ID_AL) { -+ /* Configure the ALi bridge logic. For non ALi rely on BIOS. -+ Set the south bridge enable bit */ -+ pci_read_config_byte(isa_bridge, 0x79, &tmp); -+ if(rev == 0xC2) -+ pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04); -+ else if(rev > 0xC2) -+ pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02); -+ } -+ -+ if(rev >= 0x20) { -+ if(rev < 0xC2) { -+ /* Are we paired with a UDMA capable chip */ -+ pci_read_config_byte(isa_bridge, 0x5E, &tmp); -+ if((tmp & 0x1E) == 0x12) -+ port_info[0] = port_info[1] = &info_20_udma; -+ } -+ /* -+ * CD_ROM DMA on (0x53 bit 0). Enable this even if we want -+ * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control -+ * via 0x54/55. -+ */ -+ pci_read_config_byte(pdev, 0x53, &tmp); -+ if(rev == 0x20) -+ tmp &= ~0x02; -+ tmp |= 0x01; -+ pci_write_config_byte(pdev, 0x53, tmp); -+ } -+ -+ pci_dev_put(isa_bridge); -+ pci_dev_put(north); -+ -+ ata_pci_clear_simplex(pdev); -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static struct pci_device_id ali[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5228), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229), }, -+ { 0, }, -+}; -+ -+static struct pci_driver ali_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = ali, -+ .probe = ali_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init ali_init(void) -+{ -+ return pci_register_driver(&ali_pci_driver); -+} -+ -+ -+static void __exit ali_exit(void) -+{ -+ pci_unregister_driver(&ali_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for ALi PATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, ali); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(ali_init); -+module_exit(ali_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_amd.c linux-2.6.16-rc2/drivers/scsi/pata_amd.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_amd.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_amd.c 2006-01-30 15:07:32.000000000 +0000 -@@ -0,0 +1,651 @@ -+/* -+ * pata_amd.c - AMD PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based on pata-sil680. Errata information is taken from data sheets -+ * and the amd74xx.c driver by Vojtech Pavlik. Nvidia SATA devices are -+ * claimed by sata-nv.c. -+ * -+ * TODO: -+ * Nvidia support here or seperated ? -+ * Debug cable detect -+ * Variable system clock when/if it makes sense -+ * Power management on ports -+ * -+ * -+ * Documentation publically available. -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_amd" -+#define DRV_VERSION "0.1.2" -+ -+/** -+ * timing_setup - shared timing computation and load -+ * @ap: ATA port being set up -+ * @adev: drive being configured -+ * @offset: port offset -+ * @speed: target speed -+ * @clock: clock multiplier (number of times 33MHz for this part) -+ * -+ * Perform the actual timing set up for Nvidia or AMD PATA devices. -+ * The actual devices vary so they all call into this helper function -+ * providing the clock multipler and offset (because AMD and Nvidia put -+ * the ports at different locations). -+ */ -+ -+static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offset, int speed, int clock) -+{ -+ static const unsigned char amd_cyc2udma[] = { -+ 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 -+ }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ /* Should libata have an ata_peer() function */ -+ struct ata_device *peer = &ap->device[1-adev->devno]; -+ int dn = ap->hard_port_no * 2 + adev->devno; -+ struct ata_timing at, apeer; -+ int T, UT; -+ const int amd_clock = 33333; /* KHz. */ -+ u8 t; -+ -+ T = 1000000000 / amd_clock; -+ UT = T / min_t(int, max_t(int, clock, 1), 2); -+ -+ if (ata_timing_compute(adev, speed, &at, T, UT) < 0) { -+ dev_printk(KERN_ERR, &pdev->dev, "unknown mode %d.\n", speed); -+ return; -+ } -+ -+ if (ata_dev_present(peer)) { -+ /* This may be over conservative */ -+ if(peer->dma_mode) { -+ ata_timing_compute(peer, peer->dma_mode, &apeer, T, UT); -+ ata_timing_merge(&apeer, &at, &at, ATA_TIMING_8BIT); -+ } -+ ata_timing_compute(peer, peer->pio_mode, &apeer, T, UT); -+ ata_timing_merge(&apeer, &at, &at, ATA_TIMING_8BIT); -+ } -+ -+ if (speed == XFER_UDMA_5 && amd_clock <= 33333) at.udma = 1; -+ if (speed == XFER_UDMA_6 && amd_clock <= 33333) at.udma = 15; -+ -+ /* -+ * Now do the setup work -+ */ -+ -+ /* Configure the address set up timing */ -+ pci_read_config_byte(pdev, offset + 0x0C, &t); -+ t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(at.setup, 1, 4) - 1) << ((3 - dn) << 1)); -+ pci_write_config_byte(pdev, offset + 0x0C , t); -+ -+ /* Configure the 8bit I/O timing */ -+ pci_write_config_byte(pdev, offset + 0x0E + (1 - (dn >> 1)), -+ ((FIT(at.act8b, 1, 16) - 1) << 4) | (FIT(at.rec8b, 1, 16) - 1)); -+ -+ /* Drive timing */ -+ pci_write_config_byte(pdev, offset + 0x08 + (3 - dn), -+ ((FIT(at.active, 1, 16) - 1) << 4) | (FIT(at.recover, 1, 16) - 1)); -+ -+ switch (clock) { -+ case 1: -+ t = at.udma ? (0xc0 | (FIT(at.udma, 2, 5) - 2)) : 0x03; -+ break; -+ -+ case 2: -+ t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 2, 10)]) : 0x03; -+ break; -+ -+ case 3: -+ t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 1, 10)]) : 0x03; -+ break; -+ -+ case 4: -+ t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 1, 15)]) : 0x03; -+ break; -+ -+ default: -+ return; -+ } -+ -+ /* UDMA timing */ -+ pci_write_config_byte(pdev, offset + 0x10 + (3 - dn), t); -+} -+ -+/** -+ * amd_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection. The BIOS stores this in PCI config -+ * space for us. -+ */ -+ -+static int amd_cable_detect(struct ata_port *ap) { -+ static u32 bitmask[2] = {0x00030000, 0x00C00000}; -+ u32 ata66; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_dword(pdev, 0x42, &ata66); -+ if (ata66 & bitmask[ap->hard_port_no]) -+ return ATA_CBL_PATA80; -+ else -+ return ATA_CBL_PATA40; -+ -+} -+ -+static void amd_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits amd_enable_bits[] = { -+ { 0x40, 1, 0x02, 0x02 }, -+ { 0x40, 1, 0x01, 0x01 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = amd_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * amd33_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the AMD registers for PIO mode. -+ */ -+ -+static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->pio_mode, 1); -+} -+ -+static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->pio_mode, 2); -+} -+ -+static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->pio_mode, 3); -+} -+ -+static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->pio_mode, 4); -+} -+ -+/** -+ * amd33_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the MWDMA/UDMA modes for the AMD and Nvidia -+ * chipset. -+ */ -+ -+static void amd33_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->dma_mode, 1); -+} -+ -+static void amd66_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->dma_mode, 2); -+} -+ -+static void amd100_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->dma_mode, 3); -+} -+ -+static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->dma_mode, 4); -+} -+ -+ -+/** -+ * nv_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection. The BIOS stores this in PCI config -+ * space for us. -+ */ -+ -+static int nv_cable_detect(struct ata_port *ap) { -+ static u32 bitmask[2] = {0x00030000, 0x00C00000}; -+ u32 ata66; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_dword(pdev, 0x52, &ata66); -+ if (ata66 & bitmask[ap->hard_port_no]) -+ return ATA_CBL_PATA80; -+ else -+ return ATA_CBL_PATA40; -+ -+} -+ -+static void nv_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = nv_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * nv100_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the AMD registers for PIO mode. -+ */ -+ -+static void nv100_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x50, adev->pio_mode, 3); -+} -+ -+static void nv133_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x50, adev->pio_mode, 4); -+} -+ -+/** -+ * nv100_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the MWDMA/UDMA modes for the AMD and Nvidia -+ * chipset. -+ */ -+ -+static void nv100_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x50, adev->dma_mode, 3); -+} -+ -+static void nv133_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x50, adev->dma_mode, 4); -+} -+ -+static struct scsi_host_template amd_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations amd33_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = amd33_set_piomode, -+ .set_dmamode = amd33_set_dmamode, -+ .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 = amd_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations amd66_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = amd66_set_piomode, -+ .set_dmamode = amd66_set_dmamode, -+ .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 = amd_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations amd100_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = amd100_set_piomode, -+ .set_dmamode = amd100_set_dmamode, -+ .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 = amd_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations amd133_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = amd133_set_piomode, -+ .set_dmamode = amd133_set_dmamode, -+ .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 = amd_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations nv100_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = nv100_set_piomode, -+ .set_dmamode = nv100_set_dmamode, -+ .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 = nv_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations nv133_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = nv133_set_piomode, -+ .set_dmamode = nv133_set_dmamode, -+ .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 = nv_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info[10] = { -+ { /* 0: AMD 7401 */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, /* No SWDMA */ -+ .udma_mask = 0x07, /* UDMA 33 */ -+ .port_ops = &amd33_port_ops -+ }, -+ { /* 1: Early AMD7409 - no swdma */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, /* UDMA 66 */ -+ .port_ops = &amd66_port_ops -+ }, -+ { /* 2: AMD 7409, no swdma errata */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, /* UDMA 66 */ -+ .port_ops = &amd66_port_ops -+ }, -+ { /* 3: AMD 7411 */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* UDMA 100 */ -+ .port_ops = &amd100_port_ops -+ }, -+ { /* 4: AMD 7441 */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* UDMA 100 */ -+ .port_ops = &amd100_port_ops -+ }, -+ { /* 5: AMD 8111*/ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, /* UDMA 133, no swdma */ -+ .port_ops = &amd133_port_ops -+ }, -+ { /* 6: AMD 8111 UDMA 100 (Serenade) */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* UDMA 100, no swdma */ -+ .port_ops = &amd133_port_ops -+ }, -+ { /* 7: Nvidia Nforce */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* UDMA 100 */ -+ .port_ops = &nv100_port_ops -+ }, -+ { /* 8: Nvidia Nforce2 and later */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, /* UDMA 133, no swdma */ -+ .port_ops = &nv133_port_ops -+ }, -+ { /* 9: AMD CS5536 (Geode companion) */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* UDMA 100 */ -+ .port_ops = &amd100_port_ops -+ } -+ }; -+ static struct ata_port_info *port_info[2]; -+ static int printed_version; -+ int type = id->driver_data; -+ u8 rev; -+ u8 fifo; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); -+ -+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); -+ pci_read_config_byte(pdev, 0x41, &fifo); -+ -+ /* Check for AMD7409 without swdma errata and if found adjust type */ -+ if (type == 1 && rev > 0x7) -+ type = 2; -+ -+ /* Check for AMD7411 */ -+ if (type == 3) -+ /* FIFO is broken */ -+ pci_write_config_byte(pdev, 0x41, fifo & 0x0F); -+ else -+ pci_write_config_byte(pdev, 0x41, fifo | 0xF0); -+ -+ /* Serenade ? */ -+ if (type == 5 && pdev->subsystem_vendor == PCI_VENDOR_ID_AMD && -+ pdev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) -+ type = 6; /* UDMA 100 only */ -+ -+ if (type < 3) -+ ata_pci_clear_simplex(pdev); -+ -+ /* And fire it up */ -+ -+ port_info[0] = port_info[1] = &info[type]; -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id amd[] = { -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 }, -+ { 0, }, -+}; -+ -+static struct pci_driver amd_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = amd, -+ .probe = amd_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init amd_init(void) -+{ -+ return pci_register_driver(&amd_pci_driver); -+} -+ -+static void __exit amd_exit(void) -+{ -+ pci_unregister_driver(&amd_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for AMD PATA IDE"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, amd); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(amd_init); -+module_exit(amd_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_artop.c linux-2.6.16-rc2/drivers/scsi/pata_artop.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_artop.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_artop.c 2006-02-07 13:41:48.130232936 +0000 -@@ -0,0 +1,497 @@ -+/* -+ * pata_artop.c - ARTOP ATA controller driver -+ * -+ * (C) 2006 Red Hat <alan@redhat.com> -+ * -+ * Based in part on drivers/ide/pci/aec62xx.c -+ * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> -+ * 865/865R fixes for Macintosh card version from a patch to the old -+ * driver by Thibaut VARENE <varenet@parisc-linux.org> -+ * -+ * TODO -+ * 850 serialization once the core supports it -+ * Investigate no_dsc on 850R -+ * Clock detect -+ */ -+ -+#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/device.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/ata.h> -+ -+#define DRV_NAME "pata_artop" -+#define DRV_VERSION "0.2" -+ -+/* -+ * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we -+ * get PCI bus speed functionality we leave this as 0. Its a variable -+ * for when we get the functionality and also for folks wanting to -+ * test stuff. -+ */ -+ -+static int clock = 0; -+ -+/** -+ * artop6210_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6210_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ const struct pci_bits artop_enable_bits[] = { -+ { 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */ -+ { 0x4AU, 1U, 0x04UL, 0x04UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * artop6260_cable_detect - check for 40/80 pin -+ * @ap: Port -+ * -+ * The ARTOP hardware reports the cable detect bits in register 0x49. -+ * Nothing complicated needed here. -+ */ -+ -+static int artop6260_cable_detect(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 tmp; -+ -+ pci_read_config_byte(pdev, 0x49, &tmp); -+ if (tmp & (1 >> ap->hard_port_no)) -+ return ATA_CBL_PATA40; -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * artop6260_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6260_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ const struct pci_bits artop_enable_bits[] = { -+ { 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */ -+ { 0x4AU, 1U, 0x04UL, 0x04UL }, /* port 1 */ -+ }; -+ -+ /* Odd numbered device ids are the units with enable bits (the -R cards) */ -+ if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = artop6260_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * artop6210_load_piomode - Load a set of PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device -+ * @pio: PIO mode -+ * -+ * Set PIO mode for device, in host controller PCI config space. This -+ * is used both to set PIO timings in PIO mode and also to set the -+ * matching PIO clocking for UDMA, as well as the MWDMA timings. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6210_load_piomode(struct ata_port *ap, struct ata_device *adev, unsigned int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = adev->devno + 2 * ap->hard_port_no; -+ const u16 timing[2][5] = { -+ { 0x0000, 0x000A, 0x0008, 0x0303, 0x0301 }, -+ { 0x0700, 0x070A, 0x0708, 0x0403, 0x0401 } -+ -+ }; -+ /* Load the PIO timing active/recovery bits */ -+ pci_write_config_word(pdev, 0x40 + 2 * dn, timing[clock][pio]); -+} -+ -+/** -+ * artop6210_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring -+ * -+ * Set PIO mode for device, in host controller PCI config space. For -+ * ARTOP we must also clear the UDMA bits if we are not doing UDMA. In -+ * the event UDMA is used the later call to set_dmamode will set the -+ * bits as required. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6210_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = adev->devno + 2 * ap->hard_port_no; -+ u8 ultra; -+ -+ artop6210_load_piomode(ap, adev, adev->pio_mode - XFER_PIO_0); -+ -+ /* Clear the UDMA mode bits (set_dmamode will redo this if needed) */ -+ pci_read_config_byte(pdev, 0x54, &ultra); -+ ultra &= ~(3 << (2 * dn)); -+ pci_write_config_byte(pdev, 0x54, ultra); -+} -+ -+/** -+ * artop6260_load_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring -+ * @pio: PIO mode -+ * -+ * Set PIO mode for device, in host controller PCI config space. The -+ * ARTOP6260 and relatives store the timing data differently. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6260_load_piomode (struct ata_port *ap, struct ata_device *adev, unsigned int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = adev->devno + 2 * ap->hard_port_no; -+ const u8 timing[2][5] = { -+ { 0x00, 0x0A, 0x08, 0x33, 0x31 }, -+ { 0x70, 0x7A, 0x78, 0x43, 0x41 } -+ -+ }; -+ /* Load the PIO timing active/recovery bits */ -+ pci_write_config_byte(pdev, 0x40 + dn, timing[clock][pio]); -+} -+ -+/** -+ * artop6260_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring -+ * -+ * Set PIO mode for device, in host controller PCI config space. For -+ * ARTOP we must also clear the UDMA bits if we are not doing UDMA. In -+ * the event UDMA is used the later call to set_dmamode will set the -+ * bits as required. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6260_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 ultra; -+ -+ artop6260_load_piomode(ap, adev, adev->pio_mode - XFER_PIO_0); -+ -+ /* Clear the UDMA mode bits (set_dmamode will redo this if needed) */ -+ pci_read_config_byte(pdev, 0x44 + ap->hard_port_no, &ultra); -+ ultra &= ~(7 << (4 * adev->devno)); /* One nibble per drive */ -+ pci_write_config_byte(pdev, 0x44 + ap->hard_port_no, ultra); -+} -+ -+/** -+ * artop6210_set_dmamode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: um -+ * -+ * Set DMA mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6210_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int pio; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = adev->devno + 2 * ap->hard_port_no; -+ u8 ultra; -+ -+ if (adev->dma_mode == XFER_MW_DMA_0) -+ pio = 1; -+ else -+ pio = 4; -+ -+ /* Load the PIO timing active/recovery bits */ -+ artop6210_load_piomode(ap, adev, pio); -+ -+ pci_read_config_byte(pdev, 0x54, &ultra); -+ ultra &= ~(3 << (2 * dn)); -+ -+ /* Add ultra DMA bits if in UDMA mode */ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ u8 mode = (adev->dma_mode - XFER_UDMA_0) + 1 - clock; -+ if (mode == 0) -+ mode = 1; -+ ultra |= (mode << (2 * dn)); -+ } -+ pci_write_config_byte(pdev, 0x54, ultra); -+} -+ -+/** -+ * artop6260_set_dmamode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring -+ * -+ * Set DMA mode for device, in host controller PCI config space. The -+ * ARTOP6260 and relatives store the timing data differently. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6260_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int pio = adev->pio_mode - XFER_PIO_0; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 ultra; -+ -+ if (adev->dma_mode == XFER_MW_DMA_0) -+ pio = 1; -+ else -+ pio = 4; -+ -+ /* Load the PIO timing active/recovery bits */ -+ artop6260_load_piomode(ap, adev, pio); -+ -+ /* Add ultra DMA bits if in UDMA mode */ -+ pci_read_config_byte(pdev, 0x44 + ap->hard_port_no, &ultra); -+ ultra &= ~(7 << (4 * adev->devno)); /* One nibble per drive */ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ u8 mode = adev->dma_mode - XFER_UDMA_0 + 1 - clock; -+ if (mode == 0) -+ mode = 1; -+ ultra |= (mode << (4 * adev->devno)); -+ } -+ pci_write_config_byte(pdev, 0x44 + ap->hard_port_no, ultra); -+} -+ -+static struct scsi_host_template artop_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, -+// .ordered_flush = 1, -+}; -+ -+static const struct ata_port_operations artop6210_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = artop6210_set_piomode, -+ .set_dmamode = artop6210_set_dmamode, -+ -+ .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 = artop6210_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations artop6260_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = artop6260_set_piomode, -+ .set_dmamode = artop6260_set_dmamode, -+ -+ .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 = artop6260_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+ -+/** -+ * artop_init_one - Register ARTOP ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in artop_pci_tbl matching with @pdev -+ * -+ * Called from kernel PCI layer. -+ * -+ * LOCKING: -+ * Inherited from PCI layer (may sleep). -+ * -+ * RETURNS: -+ * Zero on success, or -ERRNO value. -+ */ -+ -+static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ static int printed_version; -+ static struct ata_port_info info_6210 = { -+ .sht = &artop_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = ATA_UDMA2, -+ .port_ops = &artop6210_ops, -+ }; -+ static struct ata_port_info info_626x = { -+ .sht = &artop_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = ATA_UDMA4, -+ .port_ops = &artop6260_ops, -+ }; -+ static struct ata_port_info info_626x_fast = { -+ .sht = &artop_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &artop6260_ops, -+ }; -+ struct ata_port_info *port_info[2]; -+ struct ata_port_info *info; -+ int ports = 2; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, -+ "version " DRV_VERSION "\n"); -+ -+ if (id->driver_data == 0) { /* 6210 variant */ -+ info = &info_6210; -+ /* BIOS may have left us in UDMA, clear it before libata probe */ -+ pci_write_config_byte(pdev, 0x54, 0); -+ /* For the moment (also lacks dsc) */ -+ printk(KERN_WARNING "ARTOP 6210 requires serialize functionality not yet supported by libata.\n"); -+ printk(KERN_WARNING "Secondary ATA ports will not be activated.\n"); -+ ports = 1; -+ } -+ else if (id->driver_data == 1) /* 6260 */ -+ info = &info_626x; -+ else if (id->driver_data == 2) { /* 6260 or 6260 + fast */ -+ unsigned long io = pci_resource_start(pdev, 4); -+ u8 reg; -+ -+ info = &info_626x; -+ if (inb(io) & 0x10) -+ info = &info_626x_fast; -+ /* Mac systems come up with some registers not set as we -+ will need them */ -+ -+ /* Clear reset & test bits */ -+ pci_read_config_byte(pdev, 0x49, ®); -+ pci_write_config_byte(pdev, 0x49, reg & ~ 0x30); -+ -+ /* Enable IRQ output and burst mode */ -+ pci_read_config_byte(pdev, 0x4a, ®); -+ pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80); -+ -+ } -+ port_info[0] = port_info[1] = info; -+ return ata_pci_init_one(pdev, port_info, ports); -+} -+ -+static const struct pci_device_id artop_pci_tbl[] = { -+ { 0x1191, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0x1191, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { 0x1191, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { 0x1191, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { 0x1191, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver artop_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = artop_pci_tbl, -+ .probe = artop_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init artop_init(void) -+{ -+ return pci_register_driver(&artop_pci_driver); -+} -+ -+static void __exit artop_exit(void) -+{ -+ pci_unregister_driver(&artop_pci_driver); -+} -+ -+ -+module_init(artop_init); -+module_exit(artop_exit); -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("SCSI low-level driver for ARTOP PATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, artop_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_atiixp.c linux-2.6.16-rc2/drivers/scsi/pata_atiixp.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_atiixp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_atiixp.c 2006-02-07 13:42:02.706017080 +0000 -@@ -0,0 +1,299 @@ -+/* -+ * pata_atiixp.c - ATI PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based on -+ * -+ * linux/drivers/ide/pci/atiixp.c Version 0.01-bart2 Feb. 26, 2004 -+ * -+ * Copyright (C) 2003 ATI Inc. <hyu@ati.com> -+ * Copyright (C) 2004 Bartlomiej Zolnierkiewicz -+ * -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_atiixp" -+#define DRV_VERSION "0.1.1" -+ -+enum { -+ ATIIXP_IDE_PIO_TIMING = 0x40, -+ ATIIXP_IDE_MWDMA_TIMING = 0x44, -+ ATIIXP_IDE_PIO_CONTROL = 0x48, -+ ATIIXP_IDE_PIO_MODE = 0x4a, -+ ATIIXP_IDE_UDMA_CONTROL = 0x54, -+ ATIIXP_IDE_UDMA_MODE = 0x56 -+}; -+ -+static void atiixp_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits atiixp_enable_bits[] = { -+ { 0x48, 1, 0x01, 0x00 }, -+ { 0x48, 1, 0x08, 0x00 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA80; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * atiixp_set_pio_timing - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called by both the pio and dma setup functions to set the controller -+ * timings for PIO transfers. We must load both the mode number and -+ * timing values into the controller. -+ */ -+ -+static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev, int pio) -+{ -+ static u8 pio_timings[5] = { 0x5D, 0x47, 0x34, 0x22, 0x20 }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = 2 * ap->hard_port_no + adev->devno; -+ -+ /* Check this is correct - the order is odd in both drivers */ -+ int timing_shift = (16 * ap->hard_port_no) + 8 * (adev->devno ^ 1); -+ u16 pio_mode_data, pio_timing_data; -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_PIO_MODE, &pio_mode_data); -+ pio_mode_data &= ~(0x7 << (4 * dn)); -+ pio_mode_data |= pio << (4 * dn); -+ pci_write_config_word(pdev, ATIIXP_IDE_PIO_MODE, pio_mode_data); -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data); -+ pio_mode_data &= ~(0xFF << timing_shift); -+ pio_mode_data |= (pio_timings[pio] << timing_shift); -+ pci_write_config_word(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data); -+} -+ -+/** -+ * atiixp_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. We use a shared helper for this -+ * as the DMA setup must also adjust the PIO timing information. -+ */ -+ -+static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ atiixp_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0); -+} -+ -+/** -+ * atiixp_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the DMA mode setup. We use timing tables for most -+ * modes but must tune an appropriate PIO mode to match. -+ */ -+ -+static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u8 mwdma_timings[5] = { 0x77, 0x21, 0x20 }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dma = adev->dma_mode; -+ int dn = 2 * ap->hard_port_no + adev->devno; -+ int wanted_pio; -+ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ u16 udma_mode_data; -+ -+ dma -= XFER_UDMA_0; -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_UDMA_MODE, &udma_mode_data); -+ udma_mode_data &= ~(0x7 << (4 * dn)); -+ udma_mode_data |= dma << (4 * dn); -+ pci_write_config_word(pdev, ATIIXP_IDE_UDMA_MODE, udma_mode_data); -+ } else { -+ u16 mwdma_timing_data; -+ /* Check this is correct - the order is odd in both drivers */ -+ int timing_shift = (16 * ap->hard_port_no) + 8 * (adev->devno ^ 1); -+ -+ dma -= XFER_MW_DMA_0; -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, &mwdma_timing_data); -+ mwdma_timing_data &= ~(0xFF << timing_shift); -+ mwdma_timing_data |= (mwdma_timings[dma] << timing_shift); -+ pci_write_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, mwdma_timing_data); -+ } -+ /* -+ * We must now look at the PIO mode situation. We may need to -+ * adjust the PIO mode to keep the timings acceptable -+ */ -+ if (adev->dma_mode >= XFER_MW_DMA_2) -+ wanted_pio = 4; -+ else if (adev->dma_mode == XFER_MW_DMA_1) -+ wanted_pio = 3; -+ else if (adev->dma_mode == XFER_MW_DMA_0) -+ wanted_pio = 0; -+ else BUG(); -+ -+ if (adev->pio_mode != wanted_pio) -+ atiixp_set_pio_timing(ap, adev, wanted_pio); -+} -+ -+/** -+ * atiixp_bmdma_start - DMA start callback -+ * @qc: Command in progress -+ * -+ * When DMA begins we need to ensure that the UDMA control -+ * register for the channel is correctly set. -+ */ -+ -+static void atiixp_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = (2 * ap->hard_port_no) + adev->devno; -+ u16 tmp16; -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); -+ if (adev->dma_mode >= XFER_UDMA_0) -+ tmp16 |= (1 << dn); -+ else -+ tmp16 &= ~(1 << dn); -+ pci_write_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, tmp16); -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * atiixp_dma_stop - DMA stop callback -+ * @qc: Command in progress -+ * -+ * DMA has completed. Clear the UDMA flag as the next operations will -+ * be PIO ones not UDMA data transfer. -+ */ -+ -+static void atiixp_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = (2 * ap->hard_port_no) + qc->dev->devno; -+ u16 tmp16; -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); -+ tmp16 &= ~(1 << dn); -+ pci_write_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, tmp16); -+ ata_bmdma_stop(qc); -+} -+ -+static struct scsi_host_template atiixp_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations atiixp_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = atiixp_set_piomode, -+ .set_dmamode = atiixp_set_dmamode, -+ .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 = atiixp_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = atiixp_bmdma_start, -+ .bmdma_stop = atiixp_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &atiixp_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x06, /* No MWDMA0 support */ -+ .udma_mask = 0x3F, -+ .port_ops = &atiixp_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id atiixp[] = { -+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0, }, -+}; -+ -+static struct pci_driver atiixp_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = atiixp, -+ .probe = atiixp_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init atiixp_init(void) -+{ -+ return pci_register_driver(&atiixp_pci_driver); -+} -+ -+ -+static void __exit atiixp_exit(void) -+{ -+ pci_unregister_driver(&atiixp_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for ATI IXP200/300/400"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, atiixp); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(atiixp_init); -+module_exit(atiixp_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_cmd64x.c linux-2.6.16-rc2/drivers/scsi/pata_cmd64x.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_cmd64x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_cmd64x.c 2006-02-07 13:42:18.251653784 +0000 -@@ -0,0 +1,486 @@ -+/* -+ * pata_cmd64x.c - ATI PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based upon -+ * linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002 -+ * -+ * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. -+ * Note, this driver is not used at all on other systems because -+ * there the "BIOS" has done all of the following already. -+ * Due to massive hardware bugs, UltraDMA is only supported -+ * on the 646U2 and not on the 646U. -+ * -+ * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) -+ * Copyright (C) 1998 David S. Miller (davem@redhat.com) -+ * -+ * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> -+ * -+ * TODO -+ * Testing work -+ * Non x86 needs PIO 0 loading before we commence ident -+ * - but this belongs in libata-core -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_cmd64x" -+#define DRV_VERSION "0.1" -+ -+/* -+ * CMD64x specific registers definition. -+ */ -+ -+enum { -+ CFR = 0x50, -+ CFR_INTR_CH0 = 0x02, -+ CNTRL = 0x51, -+ CNTRL_DIS_RA0 = 0x40, -+ CNTRL_DIS_RA1 = 0x80, -+ CNTRL_ENA_2ND = 0x08, -+ CMDTIM = 0x52, -+ ARTTIM0 = 0x53, -+ DRWTIM0 = 0x54, -+ ARTTIM1 = 0x55, -+ DRWTIM1 = 0x56, -+ ARTTIM23 = 0x57, -+ ARTTIM23_DIS_RA2 = 0x04, -+ ARTTIM23_DIS_RA3 = 0x08, -+ ARTTIM23_INTR_CH1 = 0x10, -+ ARTTIM2 = 0x57, -+ ARTTIM3 = 0x57, -+ DRWTIM23 = 0x58, -+ DRWTIM2 = 0x58, -+ BRST = 0x59, -+ DRWTIM3 = 0x5b, -+ BMIDECR0 = 0x70, -+ MRDMODE = 0x71, -+ MRDMODE_INTR_CH0 = 0x04, -+ MRDMODE_INTR_CH1 = 0x08, -+ MRDMODE_BLK_CH0 = 0x10, -+ MRDMODE_BLK_CH1 = 0x20, -+ BMIDESR0 = 0x72, -+ UDIDETCR0 = 0x73, -+ DTPR0 = 0x74, -+ BMIDECR1 = 0x78, -+ BMIDECSR = 0x79, -+ BMIDESR1 = 0x7A, -+ UDIDETCR1 = 0x7B, -+ DTPR1 = 0x7C -+}; -+ -+/* Phee Phy Pho Phum */ -+ -+static void cmd64x_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+static void cmd648_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 r; -+ -+ /* Check cable detect bits */ -+ pci_read_config_byte(pdev, BMIDECSR, &r); -+ if(r & (1 << ap->hard_port_no)) -+ ap->cbl = ATA_CBL_PATA80; -+ else -+ ap->cbl = ATA_CBL_PATA40; -+ -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * cmd64x_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. -+ */ -+ -+static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct ata_timing t; -+ const unsigned long T = 1000000 / 33; -+ const u8 setup_data[] = { 0x40, 0x40, 0x40, 0x80, 0x00 }; -+ -+ u8 reg; -+ -+ /* Port layout is not logical so use a table */ -+ const u8 arttim_port[2][2] = { -+ { ARTTIM0, ARTTIM1 }, -+ { ARTTIM23, ARTTIM23 } -+ }; -+ const u8 drwtim_port[2][2] = { -+ { DRWTIM0, DRWTIM1 }, -+ { DRWTIM2, DRWTIM3 } -+ }; -+ -+ int arttim = arttim_port[ap->hard_port_no][adev->devno]; -+ int drwtim = drwtim_port[ap->hard_port_no][adev->devno]; -+ -+ -+ if (ata_timing_compute(adev, adev->pio_mode, &t, T, 0) < 0) { -+ printk(KERN_ERR DRV_NAME ": mome computation failed.\n"); -+ return; -+ } -+ if (ap->hard_port_no) { -+ /* Slave has shared address setup */ -+ struct ata_device *pair = &ap->device[adev->devno ^ 1]; -+ struct ata_timing tp; -+ -+ if(ata_dev_present(pair)) { -+ ata_timing_compute(pair, pair->pio_mode, &tp, T, 0); -+ ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); -+ } -+ } -+ -+ printk(KERN_DEBUG DRV_NAME ": active %d recovery %d setup %d.\n", -+ t.active, t.recover, t.setup); -+ if (t.recover > 16) { -+ t.active += t.recover - 16; -+ t.recover = 16; -+ } -+ if (t.active > 16) -+ t.active = 16; -+ -+ /* Now convert the clocks into values we can actually stuff into -+ the chip */ -+ -+ if (t.recover > 1) -+ t.recover--; -+ else -+ t.recover = 15; -+ -+ if (t.setup > 4) -+ t.setup = 0xC0; -+ else -+ t.setup = setup_data[t.setup]; -+ -+ t.active &= 0x0F; /* 0 = 16 */ -+ -+ /* Load setup timing */ -+ pci_read_config_byte(pdev, arttim, ®); -+ reg &= 0x3F; -+ reg |= t.setup; -+ pci_write_config_byte(pdev, arttim, reg); -+ -+ /* Load active/recovery */ -+ pci_write_config_byte(pdev, drwtim, (t.active << 4) | t.recover); -+} -+ -+/** -+ * cmd64x_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the DMA mode setup. -+ */ -+ -+static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 regU, regD; -+ -+ int pciU = UDIDETCR0 + 8 * ap->hard_port_no; -+ int pciD = BMIDESR0 + 8 * ap->hard_port_no; -+ int shift = 2 * adev->devno; -+ const u8 udma_data[] = { 0x31, 0x21, 0x11, 0x25, 0x15, 0x05 }; -+ const u8 mwdma_data[] = { 0x30, 0x20, 0x10 }; -+ -+ pci_read_config_byte(pdev, pciD, ®D); -+ pci_read_config_byte(pdev, pciU, ®U); -+ -+ regD &= ~(0x20 << shift); -+ regU &= ~(0x35 << shift); -+ -+ if (adev->dma_mode >= XFER_UDMA_0) -+ regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift; -+ else -+ regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift; -+ -+ regD |= 0x20 << adev->devno; -+ -+ pci_write_config_byte(pdev, pciU, regU); -+ pci_write_config_byte(pdev, pciD, regD); -+} -+ -+/** -+ * cmd648_dma_stop - DMA stop callback -+ * @qc: Command in progress -+ * -+ * DMA has completed. -+ */ -+ -+static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 dma_intr; -+ int dma_reg = ap->hard_port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; -+ int dma_mask = ap->hard_port_no ? ARTTIM2 : CFR; -+ -+ ata_bmdma_stop(qc); -+ -+ pci_read_config_byte(pdev, dma_reg, &dma_intr); -+ pci_write_config_byte(pdev, dma_reg, dma_intr | dma_mask); -+} -+ -+/** -+ * cmd646r1_dma_stop - DMA stop callback -+ * @qc: Command in progress -+ * -+ * Stub for now while investigating the r1 quirk in the old driver. -+ */ -+ -+static void cmd646r1_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ ata_bmdma_stop(qc); -+} -+ -+static struct scsi_host_template cmd64x_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations cmd64x_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cmd64x_set_piomode, -+ .set_dmamode = cmd64x_set_dmamode, -+ .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 = cmd64x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations cmd646r1_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cmd64x_set_piomode, -+ .set_dmamode = cmd64x_set_dmamode, -+ .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 = cmd64x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = cmd646r1_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations cmd648_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cmd64x_set_piomode, -+ .set_dmamode = cmd64x_set_dmamode, -+ .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 = cmd648_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = cmd648_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ u32 class_rev; -+ -+ static struct ata_port_info cmd_info[6] = { -+ { /* CMD 643 - no UDMA */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &cmd64x_port_ops -+ }, -+ { /* CMD 646 with broken UDMA */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &cmd64x_port_ops -+ }, -+ { /* CMD 646 with working UDMA */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA1, -+ .port_ops = &cmd64x_port_ops -+ }, -+ { /* CMD 646 rev 1 */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &cmd646r1_port_ops -+ }, -+ { /* CMD 648 */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA2, -+ .port_ops = &cmd648_port_ops -+ }, -+ { /* CMD 649 */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA3, -+ .port_ops = &cmd648_port_ops -+ } -+ }; -+ static struct ata_port_info *port_info[2], *info; -+ u8 mrdmode; -+ -+ info = &cmd_info[id->driver_data]; -+ -+ pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); -+ class_rev &= 0xFF; -+ -+ if (id->driver_data == 0) /* 643 */ -+ ata_pci_clear_simplex(pdev); -+ -+ if (pdev->device == PCI_DEVICE_ID_CMD_646) { -+ /* Does UDMA work ? */ -+ if(class_rev > 4) -+ info = &cmd_info[2]; -+ /* Early rev with other problems ? */ -+ else if(class_rev == 1) -+ info = &cmd_info[3]; -+ } -+ -+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); -+ pci_read_config_byte(pdev, MRDMODE, &mrdmode); -+ mrdmode &= ~ 0x30; /* IRQ set up */ -+ mrdmode |= 0x02; /* Memory read line enable */ -+ pci_write_config_byte(pdev, MRDMODE, mrdmode); -+ -+ /* Force PIO 0 here.. */ -+ -+ /* PPC specific fixup copied from old driver */ -+#ifdef CONFIG_PPC -+ pci_write_config_byte(pdev, UDIDETCR0, 0xF0); -+#endif -+ -+ port_info[0] = port_info[1] = info; -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static struct pci_device_id cmd64x[] = { -+ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, -+ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, -+ { 0, }, -+}; -+ -+static struct pci_driver cmd64x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = cmd64x, -+ .probe = cmd64x_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init cmd64x_init(void) -+{ -+ return pci_register_driver(&cmd64x_pci_driver); -+} -+ -+ -+static void __exit cmd64x_exit(void) -+{ -+ pci_unregister_driver(&cmd64x_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for CMD64x series PATA controllers"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, cmd64x); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(cmd64x_init); -+module_exit(cmd64x_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_cs5520.c linux-2.6.16-rc2/drivers/scsi/pata_cs5520.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_cs5520.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_cs5520.c 2006-02-07 13:42:34.495184392 +0000 -@@ -0,0 +1,322 @@ -+/* -+ * IDE tuning and bus mastering support for the CS5510/CS5520 -+ * chipsets -+ * -+ * The CS5510/CS5520 are slightly unusual devices. Unlike the -+ * typical IDE controllers they do bus mastering with the drive in -+ * PIO mode and smarter silicon. -+ * -+ * The practical upshot of this is that we must always tune the -+ * drive for the right PIO mode. We must also ignore all the blacklists -+ * and the drive bus mastering DMA information. Also to confuse matters -+ * further we can do DMA on PIO only drives. -+ * -+ * DMA on the 5510 also requires we disable_hlt() during DMA on early -+ * revisions. -+ * -+ * *** This driver is strictly experimental *** -+ * -+ * (c) Copyright Red Hat Inc 2002 -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2, or (at your option) any -+ * later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * Documentation: -+ * Not publically available. -+ */ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "cs5520" -+#define DRV_VERSION "0.3" -+ -+struct pio_clocks -+{ -+ int address; -+ int assert; -+ int recovery; -+}; -+ -+static struct pio_clocks cs5520_pio_clocks[]={ -+ {3, 6, 11}, -+ {2, 5, 6}, -+ {1, 4, 3}, -+ {1, 3, 2}, -+ {1, 2, 1} -+}; -+ -+/** -+ * cs5520_set_timings - program PIO timings -+ * @ap: ATA port -+ * @adev: ATA device -+ * -+ * Program the PIO mode timings for the controller according to the pio -+ * clocking table. -+ */ -+ -+static void cs5520_set_timings(struct ata_port *ap, struct ata_device *adev, int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int slave = adev->devno; -+ -+ pio -= XFER_PIO_0; -+ -+ /* Channel command timing */ -+ pci_write_config_byte(pdev, 0x62 + ap->hard_port_no, -+ (cs5520_pio_clocks[pio].recovery << 4) | -+ (cs5520_pio_clocks[pio].assert)); -+ /* FIXME: should these use address ? */ -+ /* Read command timing */ -+ pci_write_config_byte(pdev, 0x64 + 4*ap->hard_port_no + slave, -+ (cs5520_pio_clocks[pio].recovery << 4) | -+ (cs5520_pio_clocks[pio].assert)); -+ /* Write command timing */ -+ pci_write_config_byte(pdev, 0x66 + 4*ap->hard_port_no + slave, -+ (cs5520_pio_clocks[pio].recovery << 4) | -+ (cs5520_pio_clocks[pio].assert)); -+} -+ -+/** -+ * cs5520_enable_dma - turn on DMA bits -+ * -+ * Turn on the DMA bits for this disk. Needed because the BIOS probably -+ * has not done the work for us. Belongs in the core SATA code. -+ */ -+ -+static int cs5520_enable_dma(struct ata_port *ap, struct ata_device *adev) -+{ -+ /* Set the DMA enable/disable flag */ -+ u8 reg = inb(ap->ioaddr.bmdma_addr + 0x02); -+ reg |= 1<<(adev->devno + 5); -+ outb(reg, ap->ioaddr.bmdma_addr + 0x02); -+} -+ -+/** -+ * cs5520_set_dmamode - program DMA timings -+ * @ap: ATA port -+ * @adev: ATA device -+ * -+ * Program the DMA mode timings for the controller according to the pio -+ * clocking table. Note that this device sets the DMA timings to PIO -+ * mode values. This may seem bizarre but the 5520 architecture talks -+ * PIO mode to the disk and DMA mode to the controller so the underlying -+ * transfers are PIO timed. -+ */ -+ -+static void cs5520_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ cs5520_set_timings(ap, adev, adev->dma_mode); -+ cs5520_enable_dma(ap, adev); -+} -+ -+/** -+ * cs5520_set_piomode - program PIO timings -+ * @ap: ATA port -+ * @adev: ATA device -+ * -+ * Program the PIO mode timings for the controller according to the pio -+ * clocking table. We know pio_mode will equal dma_mode because of the -+ * CS5520 architecture. At least once we turned DMA on and wrote a -+ * mode setter. -+ */ -+ -+static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ cs5520_set_timings(ap, adev, adev->pio_mode); -+} -+ -+ -+static struct scsi_host_template cs5520_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations cs5520_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cs5520_set_piomode, -+ .set_dmamode = cs5520_set_dmamode, -+ -+ .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, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ u8 pcicfg; -+ static struct ata_probe_ent probe[2]; -+ int ports = 0; -+ -+ pci_read_config_byte(dev, 0x60, &pcicfg); -+ -+ /* Check if the ATA ports are enabled */ -+ if((pcicfg & 3) == 0) -+ return -ENODEV; -+ -+ if((pcicfg & 0x40) == 0) { -+ printk(KERN_WARNING DRV_NAME ": DMA mode disabled. Enabling.\n"); -+ pci_write_config_byte(dev, 0x60, pcicfg | 0x40); -+ } -+ -+ /* Perform set up for DMA */ -+ if(pci_enable_device_bars(dev, 1<<2)) { -+ printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); -+ return -ENODEV; -+ } -+ pci_set_master(dev); -+ if(pci_set_dma_mask(dev, DMA_32BIT_MASK)) { -+ printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n"); -+ return -ENODEV; -+ } -+ if(pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) { -+ printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n"); -+ return -ENODEV; -+ } -+ -+ /* We have to do our own plumbing as the PCI setup for this -+ chipset is non-standard so we can't punt to the libata code */ -+ -+ INIT_LIST_HEAD(&probe[0].node); -+ probe[0].dev = pci_dev_to_dev(dev); -+ probe[0].port_ops = &cs5520_port_ops; -+ probe[0].sht = &cs5520_sht; -+ probe[0].pio_mask = 0x1F; -+ probe[0].mwdma_mask = id->driver_data; -+ probe[0].irq = 14; -+ probe[0].irq_flags = SA_SHIRQ; -+ probe[0].host_flags = ATA_FLAG_SLAVE_POSS; -+ probe[0].legacy_mode = 1; -+ probe[0].n_ports = 1; -+ probe[0].port[0].cmd_addr = 0x1F0; -+ probe[0].port[0].ctl_addr = 0x3F6; -+ probe[0].port[0].altstatus_addr = 0x3F6; -+ probe[0].port[0].bmdma_addr = pci_resource_start(dev, 2); -+ -+ /* The secondary lurks at different addresses but is otherwise -+ the same beastie */ -+ -+ probe[1] = probe[0]; -+ INIT_LIST_HEAD(&probe[1].node); -+ probe[1].irq = 15; -+ probe[1].hard_port_no = 1; -+ probe[1].port[0].cmd_addr = 0x170; -+ probe[1].port[0].ctl_addr = 0x376; -+ probe[1].port[0].altstatus_addr = 0x376; -+ probe[1].port[0].bmdma_addr = pci_resource_start(dev, 2) + 8; -+ -+ /* Let libata fill in the port details */ -+ ata_std_ports(&probe[0].port[0]); -+ ata_std_ports(&probe[1].port[0]); -+ -+ /* Now add the ports that are active */ -+ if(pcicfg & 1) -+ ports += ata_device_add(&probe[0]); -+ if(pcicfg & 2) -+ ports += ata_device_add(&probe[1]); -+ if(ports) -+ return 0; -+ return -ENODEV; -+} -+ -+/** -+ * cs5520_remove_one - device unload -+ * @pdev: PCI device being removed -+ * -+ * Handle an unplug/unload event for a PCI device. Unload the -+ * PCI driver but do not use the default handler as we manage -+ * resources ourself and *MUST NOT* disable the device as it has -+ * other functions. -+ */ -+ -+static void __devexit cs5520_remove_one(struct pci_dev *pdev) -+{ -+ struct device *dev = pci_dev_to_dev(pdev); -+ struct ata_host_set *host_set = dev_get_drvdata(dev); -+ -+ ata_host_set_remove(host_set); -+ dev_set_drvdata(dev, NULL); -+} -+ -+/* For now keep DMA off. We can set it for all but A rev CS5510 once the -+ core ATA code can handle it */ -+ -+static struct pci_device_id pata_cs5520[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520), }, -+ { 0, }, -+}; -+ -+static struct pci_driver cs5520_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = pata_cs5520, -+ .probe = cs5520_init_one, -+ .remove = cs5520_remove_one -+}; -+ -+ -+static int __init cs5520_init(void) -+{ -+ return pci_register_driver(&cs5520_pci_driver); -+} -+ -+static void __exit cs5520_exit(void) -+{ -+ pci_unregister_driver(&cs5520_pci_driver); -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Cyrix CS5510/5520"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, pata_cs5520); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(cs5520_init); -+module_exit(cs5520_exit); -+ -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_cs5530.c linux-2.6.16-rc2/drivers/scsi/pata_cs5530.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_cs5530.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_cs5530.c 2006-02-07 13:42:42.392983744 +0000 -@@ -0,0 +1,313 @@ -+/* -+ * pata-cs5530.c - CS5530 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon cs5530.c by Mark Lord. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Loosely based on the piix & svwks drivers. -+ * -+ * Documentation: -+ * Available from AMD web site. -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "cs5530" -+#define DRV_VERSION "0.2" -+ -+/** -+ * cs5530_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Set our PIO requirements. This is fairly simple on the CS5530 -+ * chips. -+ */ -+ -+static void cs5530_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static unsigned int cs5530_pio_timings[2][5] = { -+ {0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010}, -+ {0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010} -+ }; -+ unsigned long base = ( ap->ioaddr.bmdma_addr & ~0x0F) + 0x20 + 0x10 * ap->hard_port_no; -+ u32 tuning; -+ int format; -+ -+ /* Find out which table to use */ -+ tuning = inl(base + 0x04); -+ format = (tuning & 0x80000000UL) ? 1 : 0; -+ -+ /* Now load the right timing register */ -+ if(adev->devno) -+ base += 0x08; -+ -+ outl(cs5530_pio_timings[format][adev->pio_mode - XFER_PIO_0], base); -+} -+ -+/** -+ * cs5530_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * We cannot mix MWDMA and UDMA without reloading timings each switch -+ * master to slave. We should implement the switch but for now we follow -+ * the old IDE driver and just avoid setting such combinations. -+ * -+ * This will come up once the SATA core grows up and develops proper -+ * timing code. -+ */ -+ -+static void cs5530_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned long base = ( ap->ioaddr.bmdma_addr & ~0x0F) + 0x20 + 0x10 * ap->hard_port_no; -+ u32 tuning, timing = 0; -+ u8 reg; -+ -+ /* Find out which table to use */ -+ tuning = inl(base + 0x04); -+ -+ switch(adev->dma_mode) { -+ case XFER_UDMA_0: -+ timing = 0x00921250;break; -+ case XFER_UDMA_1: -+ timing = 0x00911140;break; -+ case XFER_UDMA_2: -+ timing = 0x00911030;break; -+ case XFER_MW_DMA_0: -+ timing = 0x00077771;break; -+ case XFER_MW_DMA_1: -+ timing = 0x00012121;break; -+ case XFER_MW_DMA_2: -+ timing = 0x00002020;break; -+ default: -+ BUG(); -+ } -+ /* Merge in the PIO format bit */ -+ timing |= (tuning & 0x80000000UL); -+ if(adev->devno == 0) /* Master */ -+ outl(timing, base + 0x04); -+ else { -+ if(timing & 0x00100000) -+ tuning |= 0x00100000; /* UDMA for both */ -+ else -+ tuning &= ~0x00100000; /* MWDMA for both */ -+ outl(tuning, base + 0x04); -+ outl(timing, base + 0x0C); -+ } -+ -+ /* Set the DMA capable bit in the BMDMA area */ -+ reg = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); -+ reg |= (1 << (5 + adev->devno)); -+ outb(reg, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); -+} -+ -+static struct scsi_host_template cs5530_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations cs5530_port_ops = { -+/* .set_mode = cs5530_set_mode, FIXME - for master/slave */ -+ -+ .port_disable = ata_port_disable, -+ .set_piomode = cs5530_set_piomode, -+ .set_dmamode = cs5530_set_dmamode, -+ -+ .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, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * cs5530_init_one - Initialise a CS5530 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Install a driver for the newly found CS5530 companion chip. Most of -+ * this is just housekeeping. We have to set the chip up correctly and -+ * turn off various bits of emulation magic. -+ */ -+ -+static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ int compiler_warning_pointless_fix; -+ struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; -+ static struct ata_port_info info = { -+ .sht = &cs5530_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x07, -+ .port_ops = &cs5530_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ dev = NULL; -+ while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { -+ switch (dev->device) { -+ case PCI_DEVICE_ID_CYRIX_PCI_MASTER: -+ master_0 = pci_dev_get(dev); -+ break; -+ case PCI_DEVICE_ID_CYRIX_5530_LEGACY: -+ cs5530_0 = pci_dev_get(dev); -+ break; -+ } -+ } -+ if (!master_0) { -+ printk(KERN_ERR DRV_NAME ": unable to locate PCI MASTER function\n"); -+ goto fail_put; -+ } -+ if (!cs5530_0) { -+ printk(KERN_ERR DRV_NAME ": unable to locate CS5530 LEGACY function\n"); -+ goto fail_put; -+ } -+ -+ pci_set_master(cs5530_0); -+ compiler_warning_pointless_fix = pci_set_mwi(cs5530_0); -+ -+ /* -+ * Set PCI CacheLineSize to 16-bytes: -+ * --> Write 0x04 into 8-bit PCI CACHELINESIZE reg of function 0 of the cs5530 -+ * -+ * Note: This value is constant because the 5530 is only a Geode companion -+ */ -+ -+ pci_write_config_byte(cs5530_0, PCI_CACHE_LINE_SIZE, 0x04); -+ -+ /* -+ * Disable trapping of UDMA register accesses (Win98 hack): -+ * --> Write 0x5006 into 16-bit reg at offset 0xd0 of function 0 of the cs5530 -+ */ -+ -+ pci_write_config_word(cs5530_0, 0xd0, 0x5006); -+ -+ /* -+ * Bit-1 at 0x40 enables MemoryWriteAndInvalidate on internal X-bus: -+ * The other settings are what is necessary to get the register -+ * into a sane state for IDE DMA operation. -+ */ -+ -+ pci_write_config_byte(master_0, 0x40, 0x1e); -+ -+ /* -+ * Set max PCI burst size (16-bytes seems to work best): -+ * 16bytes: set bit-1 at 0x41 (reg value of 0x16) -+ * all others: clear bit-1 at 0x41, and do: -+ * 128bytes: OR 0x00 at 0x41 -+ * 256bytes: OR 0x04 at 0x41 -+ * 512bytes: OR 0x08 at 0x41 -+ * 1024bytes: OR 0x0c at 0x41 -+ */ -+ -+ pci_write_config_byte(master_0, 0x41, 0x14); -+ -+ /* -+ * These settings are necessary to get the chip -+ * into a sane state for IDE DMA operation. -+ */ -+ -+ pci_write_config_byte(master_0, 0x42, 0x00); -+ pci_write_config_byte(master_0, 0x43, 0xc1); -+ -+ pci_dev_put(master_0); -+ pci_dev_put(cs5530_0); -+ -+ /* Now kick off ATA set up */ -+ return ata_pci_init_one(dev, port_info, 2); -+ -+fail_put: -+ if(master_0) -+ pci_dev_put(master_0); -+ if(cs5530_0) -+ pci_dev_put(cs5530_0); -+ return -ENODEV; -+} -+ -+static struct pci_device_id cs5530[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), }, -+ { 0, }, -+}; -+ -+static struct pci_driver cs5530_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = cs5530, -+ .probe = cs5530_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init cs5530_init(void) -+{ -+ return pci_register_driver(&cs5530_pci_driver); -+} -+ -+ -+static void __exit cs5530_exit(void) -+{ -+ pci_unregister_driver(&cs5530_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the Cyrix/NS/AMD 5530"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, cs5530); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(cs5530_init); -+module_exit(cs5530_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_cs5535.c linux-2.6.16-rc2/drivers/scsi/pata_cs5535.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_cs5535.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_cs5535.c 2006-02-07 13:42:50.000000000 +0000 -@@ -0,0 +1,294 @@ -+/* -+ * pata-cs5535.c - CS5535 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon cs5535.c from AMD <Jens.Altmann@amd.com> as cleaned up and -+ * made readable and Linux style by Wolfgang Zuleger <wolfgang.zuleger@gmx.de -+ * and Alexander Kiausch <alex.kiausch@t-online.de> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Loosely based on the piix & svwks drivers. -+ * -+ * Documentation: -+ * Available from AMD web site. -+ * TODO -+ * Review errata to see if serializing is neccessary -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <asm/msr.h> -+ -+#define DRV_NAME "cs5535" -+#define DRV_VERSION "0.1" -+ -+/* -+ * The Geode (Aka Athlon GX now) uses an internal MSR based -+ * bus system for control. Demented but there you go. -+ */ -+ -+#define MSR_ATAC_BASE 0x51300000 -+#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0) -+#define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01) -+#define ATAC_GLD_MSR_SMI (MSR_ATAC_BASE+0x02) -+#define ATAC_GLD_MSR_ERROR (MSR_ATAC_BASE+0x03) -+#define ATAC_GLD_MSR_PM (MSR_ATAC_BASE+0x04) -+#define ATAC_GLD_MSR_DIAG (MSR_ATAC_BASE+0x05) -+#define ATAC_IO_BAR (MSR_ATAC_BASE+0x08) -+#define ATAC_RESET (MSR_ATAC_BASE+0x10) -+#define ATAC_CH0D0_PIO (MSR_ATAC_BASE+0x20) -+#define ATAC_CH0D0_DMA (MSR_ATAC_BASE+0x21) -+#define ATAC_CH0D1_PIO (MSR_ATAC_BASE+0x22) -+#define ATAC_CH0D1_DMA (MSR_ATAC_BASE+0x23) -+#define ATAC_PCI_ABRTERR (MSR_ATAC_BASE+0x24) -+ -+#define ATAC_BM0_CMD_PRIM 0x00 -+#define ATAC_BM0_STS_PRIM 0x02 -+#define ATAC_BM0_PRD 0x04 -+ -+#define CS5535_CABLE_DETECT 0x48 -+ -+#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL)==0x00009172 ) -+ -+/** -+ * cs5535_cable_detect - detect cable type -+ * @ap: Port to detect on -+ * -+ * Perform cable detection for ATA66 capable cable. Return a libata -+ * cable type. -+ */ -+ -+static int cs5535_cable_detect(struct ata_port *ap) -+{ -+ u8 cable; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_byte(pdev, CS5535_CABLE_DETECT, &cable); -+ if(cable & 1) -+ return ATA_CBL_PATA80; -+ else -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * cs5535_phy_reset - reset/probe -+ * @ap: Port to reset -+ * -+ * Reset and configure a port -+ */ -+ -+static void cs5535_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = cs5535_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * cs5535_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Set our PIO requirements. The CS5535 is pretty clean about all this -+ */ -+ -+static void cs5535_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u16 pio_timings[5] = { -+ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 -+ }; -+ static u16 pio_cmd_timings[5] = { -+ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 -+ }; -+ u32 reg, dummy; -+ struct ata_device *pair = &ap->device[1 - adev->devno]; -+ -+ int mode = adev->pio_mode - XFER_PIO_0; -+ int pairmode = pair->pio_mode - XFER_PIO_0; -+ int cmdmode = mode; -+ -+ /* Command timing has to be for the lowest of the pair of devices */ -+ if(pair->class != ATA_DEV_NONE && pair->pio_mode) -+ cmdmode = min(mode, pairmode); -+ -+ /* Write the drive timing register */ -+ wrmsr(ATAC_CH0D0_PIO + 2 * adev->devno, -+ pio_cmd_timings[cmdmode] << 16 | pio_timings[mode], 0); -+ -+ /* Write the other drive timing register if it changed */ -+ -+ if(cmdmode < pairmode) -+ wrmsr(ATAC_CH0D0_PIO + 2 * pair->devno, -+ pio_cmd_timings[cmdmode] << 16 | pio_timings[pairmode], 0); -+ -+ /* Set the PIO "format 1" bit in the DMA timing register */ -+ rdmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg, dummy); -+ wrmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg | 0x80000000UL, 0); -+} -+ -+/** -+ * cs5535_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * We cannot mix MWDMA and UDMA without reloading timings each switch -+ * master to slave. We should implement the switch but for now we follow -+ * the old IDE driver and just avoid setting such combinations. -+ * -+ * This will come up once the SATA core grows up and develops proper -+ * timing code. -+ */ -+ -+static void cs5535_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u32 udma_timings[5] = { 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 }; -+ static u32 mwdma_timings[3] = { 0x7F0FFFF3, 0x7F035352, 0x7F024241 }; -+ u32 reg, dummy; -+ int mode = adev->dma_mode; -+ -+ rdmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg, dummy); -+ reg &= 0x80000000UL; -+ if(mode >= XFER_UDMA_0) -+ reg |= udma_timings[mode - XFER_UDMA_0]; -+ else -+ reg |= mwdma_timings[mode - XFER_MW_DMA_0]; -+ wrmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg, 0); -+} -+ -+static struct scsi_host_template cs5535_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations cs5535_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cs5535_set_piomode, -+ .set_dmamode = cs5535_set_dmamode, -+ -+ .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 = cs5535_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * cs5535_init_one - Initialise a CS5530 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Install a driver for the newly found CS5530 companion chip. Most of -+ * this is just housekeeping. We have to set the chip up correctly and -+ * turn off various bits of emulation magic. -+ */ -+ -+static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &cs5535_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, -+ .port_ops = &cs5535_port_ops -+ }; -+ struct ata_port_info *ports[1] = { &info }; -+ -+ u32 timings, dummy; -+ -+ /* Check the BIOS set the initial timing clock. If not set the -+ timings for PIO0 */ -+ rdmsr(ATAC_CH0D0_PIO, timings, dummy); -+ if(CS5535_BAD_PIO(timings)) -+ wrmsr(ATAC_CH0D0_PIO, 0xF7F4F7F4UL, 0); -+ rdmsr(ATAC_CH0D1_PIO, timings, dummy); -+ if(CS5535_BAD_PIO(timings)) -+ wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0); -+ return ata_pci_init_one(dev, ports, 1); -+} -+ -+static struct pci_device_id cs5535[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_NS, 0x002D), }, -+ { 0, }, -+}; -+ -+static struct pci_driver cs5535_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = cs5535, -+ .probe = cs5535_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init cs5535_init(void) -+{ -+ return pci_register_driver(&cs5535_pci_driver); -+} -+ -+ -+static void __exit cs5535_exit(void) -+{ -+ pci_unregister_driver(&cs5535_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox, Jens Altmann, Wolfgan Zuleger, Alexander Kiausch"); -+MODULE_DESCRIPTION("low-level driver for the NS/AMD 5530"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, cs5535); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(cs5535_init); -+module_exit(cs5535_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_cypress.c linux-2.6.16-rc2/drivers/scsi/pata_cypress.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_cypress.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_cypress.c 2006-02-07 13:43:01.234119456 +0000 -@@ -0,0 +1,215 @@ -+/* -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_cypress" -+#define DRV_VERSION "0.1" -+ -+/* here are the offset definitions for the registers */ -+ -+enum { -+ CY82_IDE_CMDREG = 0x04, -+ CY82_IDE_ADDRSETUP = 0x48, -+ CY82_IDE_MASTER_IOR = 0x4C, -+ CY82_IDE_MASTER_IOW = 0x4D, -+ CY82_IDE_SLAVE_IOR = 0x4E, -+ CY82_IDE_SLAVE_IOW = 0x4F, -+ CY82_IDE_MASTER_8BIT = 0x50, -+ CY82_IDE_SLAVE_8BIT = 0x51, -+ -+ CY82_INDEX_PORT = 0x22, -+ CY82_DATA_PORT = 0x23, -+ -+ CY82_INDEX_CTRLREG1 = 0x01, -+ CY82_INDEX_CHANNEL0 = 0x30, -+ CY82_INDEX_CHANNEL1 = 0x31, -+ CY82_INDEX_TIMEOUT = 0x32 -+}; -+ -+/* Phee Phy Pho Phum */ -+ -+static void cy82c693_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * cy82c693_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. -+ */ -+ -+static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct ata_timing t; -+ const unsigned long T = 1000000 / 33; -+ short time_16, time_8; -+ u32 addr; -+ -+ if (ata_timing_compute(adev, adev->pio_mode, &t, T, 1) < 0) { -+ printk(KERN_ERR DRV_NAME ": mome computation failed.\n"); -+ return; -+ } -+ -+ time_16 = FIT(t.recover, 0, 15) | (FIT(t.active, 0, 15) << 4); -+ time_8 = FIT(t.act8b, 0, 15) | (FIT(t.rec8b, 0, 15) << 4); -+ -+ if(adev->devno == 0) { -+ pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); -+ -+ addr &= ~0x0F; /* Mask bits */ -+ addr |= FIT(t.setup, 0, 15); -+ -+ pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); -+ pci_write_config_byte(pdev, CY82_IDE_MASTER_IOR, time_16); -+ pci_write_config_byte(pdev, CY82_IDE_MASTER_IOW, time_16); -+ pci_write_config_byte(pdev, CY82_IDE_MASTER_8BIT, time_8); -+ } else { -+ pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); -+ -+ addr &= ~0xF0; /* Mask bits */ -+ addr |= (FIT(t.setup, 0, 15) << 4); -+ -+ pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); -+ pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOR, time_16); -+ pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOW, time_16); -+ pci_write_config_byte(pdev, CY82_IDE_SLAVE_8BIT, time_8); -+ } -+} -+ -+/** -+ * cy82c693_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the DMA mode setup. -+ */ -+ -+static void cy82c693_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ int reg = CY82_INDEX_CHANNEL0 + ap->hard_port_no; -+ -+ /* Be afraid, be very afraid. Magic registers in low I/O space */ -+ outb(reg, 0x22); -+ outb(adev->dma_mode - XFER_MW_DMA_0, 0x23); -+ -+ /* 0x50 gives the best behaviour on the Alpha's using this chip */ -+ outb(CY82_INDEX_TIMEOUT, 0x22); -+ outb(0x50, 0x23); -+} -+ -+static struct scsi_host_template cy82c693_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations cy82c693_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cy82c693_set_piomode, -+ .set_dmamode = cy82c693_set_dmamode, -+ .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 = cy82c693_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &cy82c693_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &cy82c693_port_ops -+ }; -+ static struct ata_port_info *port_info[1] = { &info }; -+ -+ /* Devfn 1 is the ATA primary. The secondary is magic and on devfn2. For the -+ moment we don't handle the secondary. FIXME */ -+ -+ if(PCI_FUNC(pdev->devfn) != 1) -+ return -ENODEV; -+ -+ return ata_pci_init_one(pdev, port_info, 1); -+} -+ -+static struct pci_device_id cy82c693[] = { -+ { PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0, }, -+}; -+ -+static struct pci_driver cy82c693_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = cy82c693, -+ .probe = cy82c693_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init cy82c693_init(void) -+{ -+ return pci_register_driver(&cy82c693_pci_driver); -+} -+ -+ -+static void __exit cy82c693_exit(void) -+{ -+ pci_unregister_driver(&cy82c693_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the CY82C693 PATA controller"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, cy82c693); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(cy82c693_init); -+module_exit(cy82c693_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_efar.c linux-2.6.16-rc2/drivers/scsi/pata_efar.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_efar.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_efar.c 2006-02-07 13:41:17.978816648 +0000 -@@ -0,0 +1,341 @@ -+/* -+ * pata_efar.c - EFAR PIIX clone controller driver -+ * -+ * (C) 2005 Red Hat <alan@redhat.com> -+ * -+ * Some parts based on ata_piix.c by Jeff Garzik and others. -+ * -+ * The EFAR is a PIIX4 clone with UDMA66 support. Unlike the later -+ * Intel ICH controllers the EFAR widened the UDMA mode register bits -+ * and doesn't require the funky clock selection. -+ */ -+ -+#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/device.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/ata.h> -+ -+#define DRV_NAME "pata_efar" -+#define DRV_VERSION "0.1" -+ -+/** -+ * efar_cable_detect - check for 40/80 pin -+ * @ap: Port -+ * -+ * Perform cable detection for the EFAR ATA interface. This is -+ * different to the PIIX arrangement -+ */ -+ -+static int efar_cable_detect(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 tmp; -+ -+ pci_read_config_byte(pdev, 0x47, &tmp); -+ if (tmp & (2 >> ap->hard_port_no)) -+ return ATA_CBL_PATA40; -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * efar_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void efar_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ const struct pci_bits efar_enable_bits[] = { -+ { 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */ -+ { 0x43U, 1U, 0x80UL, 0x80UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = efar_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * efar_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: um -+ * -+ * Set PIO mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int pio = adev->pio_mode - XFER_PIO_0; -+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -+ unsigned int idetm_port= ap->hard_port_no ? 0x42 : 0x40; -+ u16 idetm_data; -+ int control = 0; -+ -+ /* -+ * See Intel Document 298600-004 for the timing programing rules -+ * for PIIX/ICH. The EFAR is a clone so very similar -+ */ -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; -+ -+ if (pio > 2) -+ control |= 1; /* TIME1 enable */ -+ if (ata_pio_need_iordy(adev)) /* PIO 3/4 require IORDY */ -+ control |= 2; /* IE enable */ -+ /* Intel specifies that the PPE functionality is for disk only */ -+ if (adev->class == ATA_DEV_ATA) -+ control |= 4; /* PPE enable */ -+ -+ pci_read_config_word(dev, idetm_port, &idetm_data); -+ -+ /* Enable PPE, IE and TIME as appropriate */ -+ -+ if(adev->devno == 0) { -+ idetm_data &= 0xCCF0; -+ idetm_data |= control; -+ idetm_data |= (timings[pio][0] << 12) | -+ (timings[pio][1] << 8); -+ } else { -+ int shift = 4 * ap->hard_port_no; -+ u8 slave_data; -+ -+ idetm_data &= 0xCC0F; -+ idetm_data |= (control << 4); -+ -+ /* Slave timing in seperate register */ -+ pci_read_config_byte(dev, 0x44, &slave_data); -+ slave_data &= 0x0F << shift; -+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << shift; -+ pci_write_config_byte(dev, 0x44, slave_data); -+ } -+ -+ idetm_data |= 0x4000; /* Ensure SITRE is enabled */ -+ pci_write_config_word(dev, idetm_port, idetm_data); -+} -+ -+/** -+ * efar_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void efar_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -+ u8 master_port = ap->hard_port_no ? 0x42 : 0x40; -+ u16 master_data; -+ u8 speed = adev->dma_mode; -+ int devid = adev->devno + 2 * ap->hard_port_no; -+ u8 udma_enable; -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; -+ -+ pci_read_config_word(dev, master_port, &master_data); -+ pci_read_config_byte(dev, 0x48, &udma_enable); -+ -+ if (speed >= XFER_UDMA_0) { -+ unsigned int udma = adev->dma_mode - XFER_UDMA_0; -+ u16 udma_timing; -+ -+ udma_enable |= (1 << devid); -+ -+ /* Load the UDMA mode number */ -+ pci_read_config_word(dev, 0x4A, &udma_timing); -+ udma_timing &= ~(7 << (4 * devid)); -+ udma_timing |= udma << (4 * devid); -+ pci_write_config_word(dev, 0x4A, udma_timing); -+ } else { -+ /* -+ * MWDMA is driven by the PIO timings. We must also enable -+ * IORDY unconditionally along with TIME1. PPE has already -+ * been set when the PIO timing was set. -+ */ -+ unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0; -+ unsigned int control; -+ u8 slave_data; -+ const unsigned int needed_pio[3] = { -+ XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 -+ }; -+ int pio = needed_pio[mwdma] - XFER_PIO_0; -+ -+ control = 3; /* IORDY|TIME1 */ -+ -+ /* If the drive MWDMA is faster than it can do PIO then -+ we must force PIO into PIO0 */ -+ -+ if (adev->pio_mode < needed_pio[mwdma]) -+ /* Enable DMA timing only */ -+ control |= 8; /* PIO cycles in PIO0 */ -+ -+ if (adev->devno) { /* Slave */ -+ master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */ -+ master_data |= control << 4; -+ pci_read_config_byte(dev, 0x44, &slave_data); -+ slave_data &= (0x0F + 0xE1 * ap->hard_port_no); -+ /* Load the matching timing */ -+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->hard_port_no ? 4 : 0); -+ pci_write_config_byte(dev, 0x44, slave_data); -+ } else { /* Master */ -+ master_data &= 0xCCF4; /* Mask out IORDY|TIME1|DMAONLY -+ and master timing bits */ -+ master_data |= control; -+ master_data |= -+ (timings[pio][0] << 12) | -+ (timings[pio][1] << 8); -+ } -+ udma_enable &= ~(1 << devid); -+ pci_write_config_word(dev, master_port, master_data); -+ } -+ pci_write_config_byte(dev, 0x48, udma_enable); -+} -+ -+static struct scsi_host_template efar_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, -+// .ordered_flush = 1, -+}; -+ -+static const struct ata_port_operations efar_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = efar_set_piomode, -+ .set_dmamode = efar_set_dmamode, -+ -+ .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 = efar_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+ -+/** -+ * efar_init_one - Register EFAR ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in efar_pci_tbl matching with @pdev -+ * -+ * Called from kernel PCI layer. -+ * -+ * LOCKING: -+ * Inherited from PCI layer (may sleep). -+ * -+ * RETURNS: -+ * Zero on success, or -ERRNO value. -+ */ -+ -+static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ static struct ata_port_info info = { -+ .sht = &efar_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma1-2 */ -+ .udma_mask = 0x0f, /* UDMA 66 */ -+ .port_ops = &efar_ops, -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, -+ "version " DRV_VERSION "\n"); -+ -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id efar_pci_tbl[] = { -+ { 0x1055, 0x9130, PCI_ANY_ID, PCI_ANY_ID, }, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver efar_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = efar_pci_tbl, -+ .probe = efar_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init efar_init(void) -+{ -+ return pci_register_driver(&efar_pci_driver); -+} -+ -+static void __exit efar_exit(void) -+{ -+ pci_unregister_driver(&efar_pci_driver); -+} -+ -+ -+module_init(efar_init); -+module_exit(efar_exit); -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("SCSI low-level driver for EFAR PIIX clones"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, efar_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_hpt34x.c linux-2.6.16-rc2/drivers/scsi/pata_hpt34x.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_hpt34x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_hpt34x.c 2006-02-07 13:40:32.684702400 +0000 -@@ -0,0 +1,206 @@ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "hpt34x" -+#define DRV_VERSION "0.1" -+ -+/** -+ * hpt34x_bus_reset - reset the hpt34x bus -+ * @ap: ATA port to reset -+ * -+ * Perform the housekeeping when doing an ATA bus reeset. We just -+ * need to force the cable type. -+ */ -+ -+static void hpt34x_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA40; -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * hpt34x_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Set our PIO requirements. This is fairly simple on the HPT34x as -+ * all we have to do is clear the MWDMA and UDMA bits then load the -+ * mode number. -+ */ -+ -+static void hpt34x_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 r1, r2; -+ int dn = 2 * ap->hard_port_no + adev->devno; -+ -+ pci_read_config_dword(pdev, 0x44, &r1); -+ pci_read_config_dword(pdev, 0x48, &r2); -+ /* Load the PIO timing number */ -+ r1 &= ~(7 << (3 * dn)); -+ r1 |= (adev->pio_mode - XFER_PIO_0) << (3 * dn); -+ r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */ -+ -+ pci_write_config_dword(pdev, 0x44, r1); -+ pci_write_config_dword(pdev, 0x48, r2); -+} -+ -+/** -+ * hpt34x_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * Set up the channel for MWDMA or UDMA modes. Much the same as with -+ * PIO, load the mode number and then set MWDMA or UDMA flag. -+ */ -+ -+static void hpt34x_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 r1, r2; -+ int dn = 2 * ap->hard_port_no + adev->devno; -+ int mode_num = adev->dma_mode & 0x0F; -+ -+ pci_read_config_dword(pdev, 0x44, &r1); -+ pci_read_config_dword(pdev, 0x48, &r2); -+ /* Load the timing number */ -+ r1 &= ~(7 << (3 * dn)); -+ r1 |= (mode_num << (3 * dn)); -+ r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */ -+ -+ if(adev->dma_mode >= XFER_UDMA_0) -+ r2 |= 0x01 << dn; /* Ultra mode */ -+ else -+ r2 |= 0x10 << dn; /* MWDMA */ -+ -+ pci_write_config_dword(pdev, 0x44, r1); -+ pci_write_config_dword(pdev, 0x48, r2); -+} -+ -+static struct scsi_host_template hpt34x_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations hpt34x_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt34x_set_piomode, -+ .set_dmamode = hpt34x_set_dmamode, -+ -+ .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 = hpt34x_phy_reset, -+ -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * hpt34x_init_one - Initialise an HPT343/363 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Perform basic initialisation. The chip has a quirk that it won't -+ * function unless it is at XX00. The old ATA driver touched this up -+ * but we leave it for pci quirks to do properly. -+ */ -+ -+static int hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &hpt34x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x07, -+ .port_ops = &hpt34x_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ u16 cmd; -+ -+ /* Initialize the board */ -+ pci_write_config_word(dev, 0x80, 0x00); -+ /* Check if it is a 343 or a 363. 363 has COMMAND_MEMORY set */ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ if(cmd & PCI_COMMAND_MEMORY) -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); -+ else -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); -+ -+ /* Now kick off ATA set up */ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id hpt34x[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343), }, -+ { 0, }, -+}; -+ -+static struct pci_driver hpt34x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = hpt34x, -+ .probe = hpt34x_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init hpt34x_init(void) -+{ -+ return pci_register_driver(&hpt34x_pci_driver); -+} -+ -+ -+static void __exit hpt34x_exit(void) -+{ -+ pci_unregister_driver(&hpt34x_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the Highpoint HPT343/363"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, hpt34x); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(hpt34x_init); -+module_exit(hpt34x_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_hpt366.c linux-2.6.16-rc2/drivers/scsi/pata_hpt366.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_hpt366.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_hpt366.c 2006-02-07 13:40:40.000000000 +0000 -@@ -0,0 +1,392 @@ -+/* -+ * Libata driver for the highpoint 366 and 368 UDMA66 ATA controllers. -+ * -+ * This driver is heavily based upon: -+ * -+ * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 -+ * -+ * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> -+ * Portions Copyright (C) 2001 Sun Microsystems, Inc. -+ * Portions Copyright (C) 2003 Red Hat Inc -+ * -+ * -+ * TODO -+ * Filters if neccessary -+ * PLL mode -+ * Look into engine reset on timeout errors. Should not be -+ * required. -+ */ -+ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "hpt36x" -+#define DRV_VERSION "0.1" -+ -+struct hpt_clock { -+ u8 xfer_speed; -+ u32 timing; -+}; -+ -+/* key for bus clock timings -+ * bit -+ * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file -+ * register access. -+ * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file -+ * register access. -+ * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. -+ * during task file register access. -+ * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA -+ * xfer. -+ * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task -+ * register access. -+ * 28 UDMA enable -+ * 29 DMA enable -+ * 30 PIO_MST enable. if set, the chip is in bus master mode during -+ * PIO. -+ * 31 FIFO enable. -+ */ -+ -+static struct chipset_bus_clock_list_entry hpt366_40[] = { -+ { XFER_UDMA_4, 0x900fd943 }, -+ { XFER_UDMA_3, 0x900ad943 }, -+ { XFER_UDMA_2, 0x900bd943 }, -+ { XFER_UDMA_1, 0x9008d943 }, -+ { XFER_UDMA_0, 0x9008d943 }, -+ -+ { XFER_MW_DMA_2, 0xa008d943 }, -+ { XFER_MW_DMA_1, 0xa010d955 }, -+ { XFER_MW_DMA_0, 0xa010d9fc }, -+ -+ { XFER_PIO_4, 0xc008d963 }, -+ { XFER_PIO_3, 0xc010d974 }, -+ { XFER_PIO_2, 0xc010d997 }, -+ { XFER_PIO_1, 0xc010d9c7 }, -+ { XFER_PIO_0, 0xc018d9d9 }, -+ { 0, 0x0120d9d9 } -+}; -+ -+static struct chipset_bus_clock_list_entry hpt366_33[] = { -+ { XFER_UDMA_4, 0x90c9a731 }, -+ { XFER_UDMA_3, 0x90cfa731 }, -+ { XFER_UDMA_2, 0x90caa731 }, -+ { XFER_UDMA_1, 0x90cba731 }, -+ { XFER_UDMA_0, 0x90c8a731 }, -+ -+ { XFER_MW_DMA_2, 0xa0c8a731 }, -+ { XFER_MW_DMA_1, 0xa0c8a732 }, /* 0xa0c8a733 */ -+ { XFER_MW_DMA_0, 0xa0c8a797 }, -+ -+ { XFER_PIO_4, 0xc0c8a731 }, -+ { XFER_PIO_3, 0xc0c8a742 }, -+ { XFER_PIO_2, 0xc0d0a753 }, -+ { XFER_PIO_1, 0xc0d0a7a3 }, /* 0xc0d0a793 */ -+ { XFER_PIO_0, 0xc0d0a7aa }, /* 0xc0d0a7a7 */ -+ { 0, 0x0120a7a7 } -+}; -+ -+static struct chipset_bus_clock_list_entry hpt366_25[] = { -+ { XFER_UDMA_4, 0x90c98521 }, -+ { XFER_UDMA_3, 0x90cf8521 }, -+ { XFER_UDMA_2, 0x90cf8521 }, -+ { XFER_UDMA_1, 0x90cb8521 }, -+ { XFER_UDMA_0, 0x90cb8521 }, -+ -+ { XFER_MW_DMA_2, 0xa0ca8521 }, -+ { XFER_MW_DMA_1, 0xa0ca8532 }, -+ { XFER_MW_DMA_0, 0xa0ca8575 }, -+ -+ { XFER_PIO_4, 0xc0ca8521 }, -+ { XFER_PIO_3, 0xc0ca8532 }, -+ { XFER_PIO_2, 0xc0ca8542 }, -+ { XFER_PIO_1, 0xc0d08572 }, -+ { XFER_PIO_0, 0xc0d08585 }, -+ { 0, 0x01208585 } -+}; -+ -+/** -+ * hpt36x_find_mode - reset the hpt36x bus -+ * @ap: ATA port -+ * @speed: transfer mode -+ * -+ * Return the 32bit register programming information for this channel -+ * that matches the speed provided. -+ */ -+ -+static u32 hpt36x_find_mode(struct ata_port *ap, int speed) -+{ -+ struct hpt_clock *clocks = ap->host_set->private_data; -+ -+ while(clocks->xfer_speed) { -+ if(clocks->xfer_speed == speed) -+ return clocks->timing; -+ clocks++; -+ } -+ BUG(); -+} -+ -+/** -+ * hpt36x_phy_reset - reset the hpt36x bus -+ * @ap: ATA port to reset -+ * -+ * Perform the PHY reset handling for the 366/368 -+ */ -+ -+static void hpt36x_phy_reset(struct ata_port *ap) -+{ -+ u8 scr2, ata66; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_byte(pdev, 0x5A, &ata66); -+ if(ata66 & (1 << ap->hard_port_no)) -+ ap->cbl = ATA_CBL_PATA40; -+ else -+ ap->cbl = ATA_CBL_PATA80; -+ -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * hpt366_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Perform PIO mode setup. -+ */ -+ -+static void hpt366_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ if(fast & 0x80) { -+ fast &= ~0x80; -+ pci_write_config_byte(pdev, addr2, fast); -+ } -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt36x_find_mode(ap, adev->pio_mode); -+ mode &= ~0x8000000; /* No FIFO in PIO */ -+ mode &= ~0x30070000; /* Leave config bits alone */ -+ reg &= 0x30070000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt366_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * Set up the channel for MWDMA or UDMA modes. Much the same as with -+ * PIO, load the mode number and then set MWDMA or UDMA flag. -+ */ -+ -+static void hpt366_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ if(fast & 0x80) { -+ fast &= ~0x80; -+ pci_write_config_byte(pdev, addr2, fast); -+ } -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt36x_find_mode(ap, adev->dma_mode); -+ mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ -+ mode &= ~0xC0000000; /* Leave config bits alone */ -+ reg &= 0xC0000000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+static struct scsi_host_template hpt36x_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, -+// .ordered_flush = 1, -+}; -+ -+/* -+ * Configuration for HPT366/68 -+ */ -+ -+static struct ata_port_operations hpt366_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt366_set_piomode, -+ .set_dmamode = hpt366_set_dmamode, -+ -+ .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 = hpt36x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * hpt36x_init_one - Initialise an HPT366/368 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Initialise an HPT36x device. There are some interesting complications -+ * here. Firstly the chip may report 366 and be one of several variants. -+ * Secondly all the timings depend on the clock for the chip which we must -+ * detect and look up -+ * -+ * This is the known chip mappings. It may be missing a couple of later -+ * releases. -+ * -+ * Chip version PCI Rev Notes -+ * HPT366 4 (HPT366) 0 UDMA66 -+ * HPT366 4 (HPT366) 1 UDMA66 -+ * HPT368 4 (HPT366) 2 UDMA66 -+ * HPT37x/30x 4 (HPT366) 3+ Other driver -+ * -+ */ -+ -+static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info_hpt366 = { -+ .sht = &hpt366_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, -+ .port_ops = &hpt370_port_ops -+ }; -+ struct ata_port_info *port_info[2] = {&info_hpt366, &info_hpt366}; -+ -+ u8 irqmask; -+ u32 class_rev; -+ u32 reg1; -+ -+ struct hpt_chip *chip_table; -+ int clock_slot; -+ -+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); -+ class_rev &= 0xFF; -+ -+ /* May be a later chip in disguise. Check */ -+ /* Newer chips are in the HPT36x driver. Ignore them */ -+ if(class_rev > 2) -+ return -ENODEV; -+ -+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); -+ pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); -+ pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); -+ -+ pci_read_config_byte(dev, 0x51, &drive_fast); -+ if (drive_fast & 0x80) -+ pci_write_config_byte(dev, 0x51, drive_fast & ~0x80); -+ -+ pci_read_config_dword(dev, 0x40, ®1); -+ -+ /* PCI clocking determines the ATA timing values to use */ -+ switch((reg1 & 0x700) { -+ case 5: -+ port->private_data = hpt366_40; -+ break; -+ case 9: -+ port->private_data = hpt366_25; -+ break; -+ default: -+ port->private_data = hpt366_33; -+ break; -+ } -+ port_info[0] = port_info[1] = port; -+ /* Now kick off ATA set up */ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id hpt36x[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), }, -+ { 0, }, -+}; -+ -+static struct pci_driver hpt36x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = hpt36x, -+ .probe = hpt36x_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init hpt36x_init(void) -+{ -+ return pci_register_driver(&hpt36x_pci_driver); -+} -+ -+ -+static void __exit hpt36x_exit(void) -+{ -+ pci_unregister_driver(&hpt36x_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, hpt36x); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(hpt36x_init); -+module_exit(hpt36x_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_hpt37x.c linux-2.6.16-rc2/drivers/scsi/pata_hpt37x.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_hpt37x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_hpt37x.c 2006-02-07 13:40:49.417158680 +0000 -@@ -0,0 +1,1089 @@ -+/* -+ * Libata driver for the highpoint 37x and 30x UDMA66 ATA controllers. -+ * -+ * This driver is heavily based upon: -+ * -+ * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 -+ * -+ * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> -+ * Portions Copyright (C) 2001 Sun Microsystems, Inc. -+ * Portions Copyright (C) 2003 Red Hat Inc -+ * -+ * TODO -+ * Filters if neccessary -+ * PLL mode -+ * Investigate if we need DPLL switching on the 370 -+ * Look into engine reset on timeout errors. Should not be -+ * required. -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "hpt37x" -+#define DRV_VERSION "0.1.2" -+ -+struct hpt_clock { -+ u8 xfer_speed; -+ u32 timing; -+}; -+ -+struct hpt_chip { -+ const char *name; -+ unsigned int base; -+ struct hpt_clock *clocks[4]; -+}; -+ -+/* key for bus clock timings -+ * bit -+ * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file -+ * register access. -+ * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file -+ * register access. -+ * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. -+ * during task file register access. -+ * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA -+ * xfer. -+ * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task -+ * register access. -+ * 28 UDMA enable -+ * 29 DMA enable -+ * 30 PIO_MST enable. if set, the chip is in bus master mode during -+ * PIO. -+ * 31 FIFO enable. -+ */ -+ -+/* from highpoint documentation. these are old values */ -+static struct hpt_clock hpt370_timings_33[] = { -+/* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */ -+ { XFER_UDMA_5, 0x16454e31 }, -+ { XFER_UDMA_4, 0x16454e31 }, -+ { XFER_UDMA_3, 0x166d4e31 }, -+ { XFER_UDMA_2, 0x16494e31 }, -+ { XFER_UDMA_1, 0x164d4e31 }, -+ { XFER_UDMA_0, 0x16514e31 }, -+ -+ { XFER_MW_DMA_2, 0x26514e21 }, -+ { XFER_MW_DMA_1, 0x26514e33 }, -+ { XFER_MW_DMA_0, 0x26514e97 }, -+ -+ { XFER_PIO_4, 0x06514e21 }, -+ { XFER_PIO_3, 0x06514e22 }, -+ { XFER_PIO_2, 0x06514e33 }, -+ { XFER_PIO_1, 0x06914e43 }, -+ { XFER_PIO_0, 0x06914e57 }, -+ { 0, 0x06514e57 } -+}; -+ -+static struct hpt_clock hpt370_timings_66[] = { -+ { XFER_UDMA_5, 0x14846231 }, -+ { XFER_UDMA_4, 0x14886231 }, -+ { XFER_UDMA_3, 0x148c6231 }, -+ { XFER_UDMA_2, 0x148c6231 }, -+ { XFER_UDMA_1, 0x14906231 }, -+ { XFER_UDMA_0, 0x14986231 }, -+ -+ { XFER_MW_DMA_2, 0x26514e21 }, -+ { XFER_MW_DMA_1, 0x26514e33 }, -+ { XFER_MW_DMA_0, 0x26514e97 }, -+ -+ { XFER_PIO_4, 0x06514e21 }, -+ { XFER_PIO_3, 0x06514e22 }, -+ { XFER_PIO_2, 0x06514e33 }, -+ { XFER_PIO_1, 0x06914e43 }, -+ { XFER_PIO_0, 0x06914e57 }, -+ { 0, 0x06514e57 } -+}; -+ -+/* these are the current (4 sep 2001) timings from highpoint */ -+static struct hpt_clock hpt370a_timings_33[] = { -+ { XFER_UDMA_5, 0x12446231 }, -+ { XFER_UDMA_4, 0x12446231 }, -+ { XFER_UDMA_3, 0x126c6231 }, -+ { XFER_UDMA_2, 0x12486231 }, -+ { XFER_UDMA_1, 0x124c6233 }, -+ { XFER_UDMA_0, 0x12506297 }, -+ -+ { XFER_MW_DMA_2, 0x22406c31 }, -+ { XFER_MW_DMA_1, 0x22406c33 }, -+ { XFER_MW_DMA_0, 0x22406c97 }, -+ -+ { XFER_PIO_4, 0x06414e31 }, -+ { XFER_PIO_3, 0x06414e42 }, -+ { XFER_PIO_2, 0x06414e53 }, -+ { XFER_PIO_1, 0x06814e93 }, -+ { XFER_PIO_0, 0x06814ea7 }, -+ { 0, 0x06814ea7 } -+}; -+ -+/* 2x 33MHz timings */ -+static struct hpt_clock hpt370a_timings_66[] = { -+ { XFER_UDMA_5, 0x1488e673 }, -+ { XFER_UDMA_4, 0x1488e673 }, -+ { XFER_UDMA_3, 0x1498e673 }, -+ { XFER_UDMA_2, 0x1490e673 }, -+ { XFER_UDMA_1, 0x1498e677 }, -+ { XFER_UDMA_0, 0x14a0e73f }, -+ -+ { XFER_MW_DMA_2, 0x2480fa73 }, -+ { XFER_MW_DMA_1, 0x2480fa77 }, -+ { XFER_MW_DMA_0, 0x2480fb3f }, -+ -+ { XFER_PIO_4, 0x0c82be73 }, -+ { XFER_PIO_3, 0x0c82be95 }, -+ { XFER_PIO_2, 0x0c82beb7 }, -+ { XFER_PIO_1, 0x0d02bf37 }, -+ { XFER_PIO_0, 0x0d02bf5f }, -+ { 0, 0x0d02bf5f } -+}; -+ -+static struct hpt_clock hpt370a_timings_50[] = { -+ { XFER_UDMA_5, 0x12848242 }, -+ { XFER_UDMA_4, 0x12ac8242 }, -+ { XFER_UDMA_3, 0x128c8242 }, -+ { XFER_UDMA_2, 0x120c8242 }, -+ { XFER_UDMA_1, 0x12148254 }, -+ { XFER_UDMA_0, 0x121882ea }, -+ -+ { XFER_MW_DMA_2, 0x22808242 }, -+ { XFER_MW_DMA_1, 0x22808254 }, -+ { XFER_MW_DMA_0, 0x228082ea }, -+ -+ { XFER_PIO_4, 0x0a81f442 }, -+ { XFER_PIO_3, 0x0a81f443 }, -+ { XFER_PIO_2, 0x0a81f454 }, -+ { XFER_PIO_1, 0x0ac1f465 }, -+ { XFER_PIO_0, 0x0ac1f48a }, -+ { 0, 0x0ac1f48a } -+}; -+ -+static struct hpt_clock hpt372_timings_33[] = { -+ { XFER_UDMA_6, 0x1c81dc62 }, -+ { XFER_UDMA_5, 0x1c6ddc62 }, -+ { XFER_UDMA_4, 0x1c8ddc62 }, -+ { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */ -+ { XFER_UDMA_2, 0x1c91dc62 }, -+ { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */ -+ { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */ -+ -+ { XFER_MW_DMA_2, 0x2c829262 }, -+ { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */ -+ { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */ -+ -+ { XFER_PIO_4, 0x0c829c62 }, -+ { XFER_PIO_3, 0x0c829c84 }, -+ { XFER_PIO_2, 0x0c829ca6 }, -+ { XFER_PIO_1, 0x0d029d26 }, -+ { XFER_PIO_0, 0x0d029d5e }, -+ { 0, 0x0d029d5e } -+}; -+ -+static struct hpt_clock hpt372_timings_50[] = { -+ { XFER_UDMA_5, 0x12848242 }, -+ { XFER_UDMA_4, 0x12ac8242 }, -+ { XFER_UDMA_3, 0x128c8242 }, -+ { XFER_UDMA_2, 0x120c8242 }, -+ { XFER_UDMA_1, 0x12148254 }, -+ { XFER_UDMA_0, 0x121882ea }, -+ -+ { XFER_MW_DMA_2, 0x22808242 }, -+ { XFER_MW_DMA_1, 0x22808254 }, -+ { XFER_MW_DMA_0, 0x228082ea }, -+ -+ { XFER_PIO_4, 0x0a81f442 }, -+ { XFER_PIO_3, 0x0a81f443 }, -+ { XFER_PIO_2, 0x0a81f454 }, -+ { XFER_PIO_1, 0x0ac1f465 }, -+ { XFER_PIO_0, 0x0ac1f48a }, -+ { 0, 0x0a81f443 } -+}; -+ -+static struct hpt_clock hpt372_timings_66[] = { -+ { XFER_UDMA_6, 0x1c869c62 }, -+ { XFER_UDMA_5, 0x1cae9c62 }, -+ { XFER_UDMA_4, 0x1c8a9c62 }, -+ { XFER_UDMA_3, 0x1c8e9c62 }, -+ { XFER_UDMA_2, 0x1c929c62 }, -+ { XFER_UDMA_1, 0x1c9a9c62 }, -+ { XFER_UDMA_0, 0x1c829c62 }, -+ -+ { XFER_MW_DMA_2, 0x2c829c62 }, -+ { XFER_MW_DMA_1, 0x2c829c66 }, -+ { XFER_MW_DMA_0, 0x2c829d2e }, -+ -+ { XFER_PIO_4, 0x0c829c62 }, -+ { XFER_PIO_3, 0x0c829c84 }, -+ { XFER_PIO_2, 0x0c829ca6 }, -+ { XFER_PIO_1, 0x0d029d26 }, -+ { XFER_PIO_0, 0x0d029d5e }, -+ { 0, 0x0d029d26 } -+}; -+ -+static struct hpt_clock hpt374_timings_33[] = { -+ { XFER_UDMA_6, 0x12808242 }, -+ { XFER_UDMA_5, 0x12848242 }, -+ { XFER_UDMA_4, 0x12ac8242 }, -+ { XFER_UDMA_3, 0x128c8242 }, -+ { XFER_UDMA_2, 0x120c8242 }, -+ { XFER_UDMA_1, 0x12148254 }, -+ { XFER_UDMA_0, 0x121882ea }, -+ -+ { XFER_MW_DMA_2, 0x22808242 }, -+ { XFER_MW_DMA_1, 0x22808254 }, -+ { XFER_MW_DMA_0, 0x228082ea }, -+ -+ { XFER_PIO_4, 0x0a81f442 }, -+ { XFER_PIO_3, 0x0a81f443 }, -+ { XFER_PIO_2, 0x0a81f454 }, -+ { XFER_PIO_1, 0x0ac1f465 }, -+ { XFER_PIO_0, 0x0ac1f48a }, -+ { 0, 0x06814e93 } -+}; -+ -+static struct hpt_chip hpt370 = { -+ "HPT370", -+ 48, -+ { -+ hpt370_timings_33, -+ NULL, -+ NULL, -+ hpt370_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt370a = { -+ "HPT370A", -+ 48, -+ { -+ hpt370a_timings_33, -+ NULL, -+ hpt370a_timings_50, -+ hpt370a_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt372 = { -+ "HPT372", -+ 55, -+ { -+ hpt372_timings_33, -+ NULL, -+ hpt372_timings_50, -+ hpt372_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt302 = { -+ "HPT302", -+ 66, -+ { -+ hpt372_timings_33, -+ NULL, -+ hpt372_timings_50, -+ hpt372_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt371 = { -+ "HPT371", -+ 66, -+ { -+ hpt372_timings_33, -+ NULL, -+ hpt372_timings_50, -+ hpt372_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt372a = { -+ "HPT372A", -+ 66, -+ { -+ hpt372_timings_33, -+ NULL, -+ hpt372_timings_50, -+ hpt372_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt374 = { -+ "HPT374", -+ 48, -+ { -+ hpt374_timings_33, -+ NULL, -+ NULL, -+ NULL -+ } -+}; -+ -+/** -+ * hpt37x_find_mode - reset the hpt37x bus -+ * @ap: ATA port -+ * @speed: transfer mode -+ * -+ * Return the 32bit register programming information for this channel -+ * that matches the speed provided. -+ */ -+ -+static u32 hpt37x_find_mode(struct ata_port *ap, int speed) -+{ -+ struct hpt_clock *clocks = ap->host_set->private_data; -+ -+ while(clocks->xfer_speed) { -+ if(clocks->xfer_speed == speed) -+ return clocks->timing; -+ clocks++; -+ } -+ BUG(); -+} -+ -+/** -+ * hpt37x_phy_reset - reset the hpt37x bus -+ * @ap: ATA port to reset -+ * -+ * Perform the PHY reset handling for the 370/372 and 374 func 0 -+ */ -+ -+static void hpt37x_phy_reset(struct ata_port *ap) -+{ -+ u8 scr2, ata66; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_byte(pdev, 0x5B, &scr2); -+ pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01); -+ /* Cable register now active */ -+ pci_read_config_byte(pdev, 0x5A, &ata66); -+ /* Restore state */ -+ pci_write_config_byte(pdev, 0x5B, scr2); -+ -+ if(ata66 & (1 << ap->hard_port_no)) -+ ap->cbl = ATA_CBL_PATA40; -+ else -+ ap->cbl = ATA_CBL_PATA80; -+ -+ /* Reset the state machine */ -+ pci_write_config_byte(pdev, 0x50, 0x37); -+ pci_write_config_byte(pdev, 0x54, 0x37); -+ udelay(100); -+ -+ printk("BUS RESET\n"); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * hpt374_phy_reset - reset the hpt374 -+ * @ap: ATA port to reset -+ * -+ * The 374 cable detect is a little different due to the extra -+ * channels. The function 0 channels work like usual but function 1 -+ * is special -+ */ -+ -+static void hpt374_phy_reset(struct ata_port *ap) -+{ -+ u16 mcr3, mcr6; -+ u8 ata66; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ if(!(PCI_FUNC(pdev->devfn) & 1)) { -+ hpt37x_phy_reset(ap); -+ return; -+ } -+ /* Do the extra channel work */ -+ pci_read_config_word(pdev, 0x52, &mcr3); -+ pci_read_config_word(pdev, 0x56, &mcr6); -+ /* Set bit 15 of 0x52 to enable TCBLID as input -+ Set bit 15 of 0x56 to enable FCBLID as input -+ */ -+ pci_write_config_word(pdev, 0x52, mcr3 | 0x8000); -+ pci_write_config_word(pdev, 0x56, mcr6 | 0x8000); -+ pci_read_config_byte(pdev, 0x5A, &ata66); -+ /* Reset TCBLID/FCBLID to output */ -+ pci_write_config_word(pdev, 0x52, mcr3); -+ pci_write_config_word(pdev, 0x56, mcr6); -+ -+ if(ata66 & (1 << ap->hard_port_no)) -+ ap->cbl = ATA_CBL_PATA40; -+ else -+ ap->cbl = ATA_CBL_PATA80; -+ -+ /* Reset the state machine */ -+ pci_write_config_byte(pdev, 0x50, 0x37); -+ pci_write_config_byte(pdev, 0x54, 0x37); -+ udelay(100); -+ -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+ -+/** -+ * hpt370_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Perform PIO mode setup. -+ */ -+ -+static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x02; -+ fast |= 0x01; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt37x_find_mode(ap, adev->pio_mode); -+ mode &= ~0x8000000; /* No FIFO in PIO */ -+ mode &= ~0x30070000; /* Leave config bits alone */ -+ reg &= 0x30070000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt370_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * Set up the channel for MWDMA or UDMA modes. Much the same as with -+ * PIO, load the mode number and then set MWDMA or UDMA flag. -+ */ -+ -+static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x02; -+ fast |= 0x01; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt37x_find_mode(ap, adev->dma_mode); -+ mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ -+ mode &= ~0xC0000000; /* Leave config bits alone */ -+ reg &= 0xC0000000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt370_bmdma_start - DMA engine begin -+ * @qc: ATA command -+ * -+ * The 370 and 370A want us to reset the DMA engine each time we -+ * use it. The 372 and later are fine. -+ */ -+ -+static void hpt370_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ pci_write_config_byte(pdev, 0x50 + 4 * ap->hard_port_no, 0x37); -+ udelay(10); -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * hpt370_bmdma_end - DMA engine stop -+ * @qc: ATA command -+ * -+ * Work around the HPT370 DMA engine. -+ */ -+ -+static void hpt370_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 dma_stat = inb(ap->ioaddr.bmdma_addr + 2); -+ u8 dma_cmd; -+ unsigned long bmdma = ap->ioaddr.bmdma_addr; -+ -+ if(dma_stat & 0x01) { -+ udelay(20); -+ dma_stat = inb(bmdma + 2); -+ } -+ if(dma_stat & 0x01) { -+ /* Clear the engine */ -+ pci_write_config_byte(pdev, 0x50 + 4 * ap->hard_port_no, 0x37); -+ udelay(10); -+ /* Stop DMA */ -+ dma_cmd = inb(bmdma ); -+ outb(dma_cmd & 0xFE, bmdma); -+ /* Clear Error */ -+ dma_stat = inb(bmdma + 2); -+ outb(dma_stat | 0x06 , bmdma + 2); -+ /* Clear the engine */ -+ pci_write_config_byte(pdev, 0x50 + 4 * ap->hard_port_no, 0x37); -+ udelay(10); -+ } -+ ata_bmdma_stop(qc); -+} -+ -+/** -+ * hpt372_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Perform PIO mode setup. -+ */ -+ -+static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x07; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt37x_find_mode(ap, adev->pio_mode); -+ -+ printk("Find mode for %d reports %X\n", adev->pio_mode, mode); -+ mode &= ~0x8000000; /* No FIFO in PIO */ -+ mode &= ~0x30070000; /* Leave config bits alone */ -+ reg &= 0x30070000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt372_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * Set up the channel for MWDMA or UDMA modes. Much the same as with -+ * PIO, load the mode number and then set MWDMA or UDMA flag. -+ */ -+ -+static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x07; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt37x_find_mode(ap, adev->dma_mode); -+ printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode); -+ mode &= ~0xC0000000; /* Leave config bits alone */ -+ mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ -+ reg &= 0xC0000000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt37x_bmdma_end - DMA engine stop -+ * @qc: ATA command -+ * -+ * Clean up after the HPT372 and later DMA engine -+ */ -+ -+static void hpt37x_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int mscreg = 0x50 + 2 * ap->hard_port_no; -+ u8 bwsr_stat, msc_stat; -+ -+ pci_read_config_byte(pdev, 0x6A, &bwsr_stat); -+ pci_read_config_byte(pdev, mscreg, &msc_stat); -+ if(bwsr_stat & (1 << ap->hard_port_no)) -+ pci_write_config_byte(pdev, mscreg, msc_stat | 0x30); -+ ata_bmdma_stop(qc); -+} -+ -+ -+static struct scsi_host_template hpt37x_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, -+// .ordered_flush = 1, -+}; -+ -+/* -+ * Configuration for HPT370, HPT370A -+ */ -+ -+static struct ata_port_operations hpt370_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt370_set_piomode, -+ .set_dmamode = hpt370_set_dmamode, -+ -+ .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 = hpt37x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = hpt370_bmdma_start, -+ .bmdma_stop = hpt370_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Configuration for HPT372, HPT371, HPT302. Slightly different PIO -+ * and DMA mode setting functionality. -+ */ -+ -+static struct ata_port_operations hpt372_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt372_set_piomode, -+ .set_dmamode = hpt372_set_dmamode, -+ -+ .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 = hpt37x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = hpt37x_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .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, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Configuration for HPT374. Mode setting works like 372 and friends -+ * but we have a different cable detection procedure. -+ */ -+ -+static struct ata_port_operations hpt374_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt372_set_piomode, -+ .set_dmamode = hpt372_set_dmamode, -+ -+ .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 = hpt374_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = hpt37x_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .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, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * htp37x_clock_slot - Turn timing to PC clock entry -+ * @freq: Reported frequency timing -+ * @base: Base timing -+ * -+ * Turn the timing data intoa clock slot (0 for 33, 1 for 40, 2 for 50 -+ * and 3 for 66Mhz) -+ */ -+ -+static int hpt37x_clock_slot(unsigned int freq, unsigned int base) -+{ -+ unsigned int f = (base * freq) / 192; /* Mhz */ -+ if(f < 40) -+ return 0; /* 33Mhz slot */ -+ if(f < 45) -+ return 1; /* 40Mhz slot */ -+ if(f < 55) -+ return 2; /* 50Mhz slot */ -+ return 3; /* 60Mhz slot */ -+} -+ -+/** -+ * hpt37x_calibrate_dpll - Calibrate the DPLL loop -+ * @dev: PCI device -+ * -+ * Perform a calibration cycle on the HPT37x DPLL. Returns 1 if this -+ * succeeds -+ */ -+ -+static int hpt37x_calibrate_dpll(struct pci_dev *dev) -+{ -+ u8 reg5b; -+ u32 reg5c; -+ int tries; -+ -+ for(tries = 0; tries < 0x5000; tries++) { -+ udelay(50); -+ pci_read_config_byte(dev, 0x5b, ®5b); -+ if(reg5b & 0x80) { -+ /* See if it stays set */ -+ for(tries = 0; tries < 0x1000; tries ++) { -+ pci_read_config_byte(dev, 0x5b, ®5b); -+ /* Failed ? */ -+ if((reg5b & 0x80) == 0) -+ return 0; -+ } -+ /* Turn off tuning, we have the DPLL set */ -+ pci_read_config_dword(dev, 0x5c, ®5c); -+ pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100); -+ return 1; -+ } -+ } -+ /* Never went stable */ -+ return 0; -+} -+/** -+ * hpt37x_init_one - Initialise an HPT37X/302 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Initialise an HPT37x device. There are some interesting complications -+ * here. Firstly the chip may report 366 and be one of several variants. -+ * Secondly all the timings depend on the clock for the chip which we must -+ * detect and look up -+ * -+ * This is the known chip mappings. It may be missing a couple of later -+ * releases. -+ * -+ * Chip version PCI Rev Notes -+ * HPT366 4 (HPT366) 0 Other driver -+ * HPT366 4 (HPT366) 1 Other driver -+ * HPT368 4 (HPT366) 2 Other driver -+ * HPT370 4 (HPT366) 3 UDMA100 -+ * HPT370A 4 (HPT366) 4 UDMA100 -+ * HPT372 4 (HPT366) 5 UDMA133 (1) -+ * HPT372N 4 (HPT366) 6 Other driver -+ * HPT372A 5 (HPT372) 1 UDMA133 (1) -+ * HPT372N 5 (HPT372) 2 Other driver -+ * HPT302 6 (HPT302) 1 UDMA133 -+ * HPT302N 6 (HPT302) 2 Other driver -+ * HPT371 7 (HPT371) * UDMA133 -+ * HPT374 8 (HPT374) * UDMA133 4 channel -+ * HPT372N 9 (HPT372N) * Other driver -+ * -+ * (1) UDMA133 support depends on the bus clock -+ */ -+ -+static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ /* HPT370 and HPT370A - UDMA100 */ -+ static struct ata_port_info info_hpt370 = { -+ .sht = &hpt37x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &hpt370_port_ops -+ }; -+ /* HPT371, 372 and friends - UDMA133 */ -+ static struct ata_port_info info_hpt372 = { -+ .sht = &hpt37x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &hpt372_port_ops -+ }; -+ /* HPT371, 372 and friends - UDMA100 at 50MHz clock */ -+ static struct ata_port_info info_hpt372_50 = { -+ .sht = &hpt37x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &hpt372_port_ops -+ }; -+ /* HPT374 - UDMA133 */ -+ static struct ata_port_info info_hpt374 = { -+ .sht = &hpt37x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &hpt374_port_ops -+ }; -+ -+ struct ata_port_info *port_info[2]; -+ struct ata_port_info *port; -+ -+ u8 irqmask; -+ u32 class_rev; -+ u32 freq; -+ -+ int MHz[4] = { 33, 40, 50, 66 }; -+ struct hpt_chip *chip_table; -+ int clock_slot; -+ -+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); -+ class_rev &= 0xFF; -+ -+ if(dev->device == PCI_DEVICE_ID_TTI_HPT366) { -+ /* May be a later chip in disguise. Check */ -+ /* Older chips are in the HPT366 driver. Ignore them */ -+ if(class_rev < 3) -+ return -ENODEV; -+ /* N series chips have their own driver. Ignore */ -+ if(class_rev == 6) -+ return -ENODEV; -+ -+ switch(class_rev) { -+ case 3: -+ port = &info_hpt370; -+ chip_table = &hpt370; -+ break; -+ case 4: -+ port = &info_hpt370; -+ chip_table = &hpt370a; -+ break; -+ case 5: -+ port = &info_hpt372; -+ chip_table = &hpt372; -+ break; -+ default: -+ printk(KERN_ERR "pata_hpt37x: Unknown HPT366 subtype please report (%d).\n", class_rev); -+ return -ENODEV; -+ } -+ } else { -+ switch(dev->device) { -+ case PCI_DEVICE_ID_TTI_HPT372: -+ /* 372N if rev >= 2*/ -+ if(class_rev >= 2) -+ return -ENODEV; -+ port = &info_hpt372; -+ chip_table = &hpt372a; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT302: -+ /* 302N if rev > 1 */ -+ if(class_rev > 1) -+ return -ENODEV; -+ port = &info_hpt372; -+ /* Check this */ -+ chip_table = &hpt302; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT371: -+ port = &info_hpt372; -+ chip_table = &hpt371; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT374: -+ chip_table = &hpt374; -+ port = &info_hpt374; -+ break; -+ default: -+ printk(KERN_ERR "pata_hpt37x: PCI table is bogus please report (%d).\n", dev->device); -+ return -ENODEV; -+ } -+ } -+ /* Ok so this is a chip we support */ -+ -+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); -+ pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); -+ pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); -+ -+ pci_read_config_byte(dev, 0x5A, &irqmask); -+ irqmask &= ~0x10; -+ pci_write_config_byte(dev, 0x5a, irqmask); -+ -+ /* -+ * default to pci clock. make sure MA15/16 are set to output -+ * to prevent drives having problems with 40-pin cables. Needed -+ * for some drives such as IBM-DTLA which will not enter ready -+ * state on reset when PDIAG is a input. -+ */ -+ -+ pci_write_config_byte(dev, 0x5b, 0x23); -+ -+ pci_read_config_dword(dev, 0x70, &freq); -+ if((freq >> 12) != 0xABCDE) { -+ int i; -+ u8 sr; -+ u32 total = 0; -+ -+ printk(KERN_WARNING "pata_hpt37x: BIOS has not set timing clocks.\n"); -+ -+ /* This is the process the HPT371 BIOS is reported to use */ -+ for(i = 0; i < 128; i++) { -+ pci_read_config_byte(dev, 0x78, &sr); -+ total += sr; -+ udelay(15); -+ } -+ freq = total / 128; -+ } -+ freq &= 0x1FF; -+ -+ /* -+ * Turn the frequency check into a band and then find a timing -+ * table to match it. -+ */ -+ -+ clock_slot = hpt37x_clock_slot(freq, chip_table->base); -+ if(chip_table->clocks[clock_slot] == NULL) { -+ /* -+ * We need to try PLL mode instead -+ */ -+ unsigned int f_low = (MHz[clock_slot] * chip_table->base) / 192; -+ unsigned int f_high = f_low + 2; -+ int adjust; -+ -+ for(adjust = 0; adjust < 8; adjust++) { -+ if(hpt37x_calibrate_dpll(dev)) -+ break; -+ /* See if it'll settle at a fractionally different clock */ -+ if((adjust & 3) == 3) { -+ f_low --; -+ f_high ++; -+ } -+ pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); -+ } -+ if(adjust == 8) { -+ printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n"); -+ return -ENODEV; -+ } -+ /* Check if this works for all cases */ -+ port->private_data = hpt370_timings_66; -+ -+ printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]); -+ } else { -+ port->private_data = chip_table->clocks[clock_slot]; -+ /* -+ * Perform a final fixup. The 371 and 372 clock determines -+ * if UDMA133 is available. -+ */ -+ -+ if(clock_slot == 2 && chip_table == &hpt372) { /* 50Mhz */ -+ printk(KERN_WARNING "pata_hpt37x: No UDMA133 support available with 50MHz bus clock.\n"); -+ if(port == &info_hpt372) -+ port = &info_hpt372_50; -+ else BUG(); -+ } -+ printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]); -+ } -+ port_info[0] = port_info[1] = port; -+ /* Now kick off ATA set up */ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id hpt37x[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT371), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), }, -+ { 0, }, -+}; -+ -+static struct pci_driver hpt37x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = hpt37x, -+ .probe = hpt37x_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init hpt37x_init(void) -+{ -+ return pci_register_driver(&hpt37x_pci_driver); -+} -+ -+ -+static void __exit hpt37x_exit(void) -+{ -+ pci_unregister_driver(&hpt37x_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the Highpoint HPT37x/30x"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, hpt37x); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(hpt37x_init); -+module_exit(hpt37x_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_hpt3x2n.c linux-2.6.16-rc2/drivers/scsi/pata_hpt3x2n.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_hpt3x2n.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_hpt3x2n.c 2006-02-07 13:50:40.927235480 +0000 -@@ -0,0 +1,580 @@ -+/* -+ * Libata driver for the highpoint 372N and 302N UDMA66 ATA controllers. -+ * -+ * This driver is heavily based upon: -+ * -+ * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 -+ * -+ * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> -+ * Portions Copyright (C) 2001 Sun Microsystems, Inc. -+ * Portions Copyright (C) 2003 Red Hat Inc -+ * -+ * -+ * TODO -+ * 371N -+ * Work out best PLL policy -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "hpt3x2n" -+#define DRV_VERSION "0.1" -+ -+enum { -+ HPT_PCI_FAST = (1 << 31), -+ PCI66 = (1 << 1), -+ USE_DPLL = (1 << 0) -+}; -+ -+struct hpt_clock { -+ u8 xfer_speed; -+ u32 timing; -+}; -+ -+struct hpt_chip { -+ const char *name; -+ struct hpt_clock *clocks[3]; -+}; -+ -+/* key for bus clock timings -+ * bit -+ * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file -+ * register access. -+ * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file -+ * register access. -+ * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. -+ * during task file register access. -+ * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA -+ * xfer. -+ * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task -+ * register access. -+ * 28 UDMA enable -+ * 29 DMA enable -+ * 30 PIO_MST enable. if set, the chip is in bus master mode during -+ * PIO. -+ * 31 FIFO enable. -+ */ -+ -+/* 66MHz DPLL clocks */ -+ -+static struct hpt_clock hpt3x2n_clocks[] = { -+ { XFER_UDMA_7, 0x1c869c62 }, -+ { XFER_UDMA_6, 0x1c869c62 }, -+ { XFER_UDMA_5, 0x1c8a9c62 }, -+ { XFER_UDMA_4, 0x1c8a9c62 }, -+ { XFER_UDMA_3, 0x1c8e9c62 }, -+ { XFER_UDMA_2, 0x1c929c62 }, -+ { XFER_UDMA_1, 0x1c9a9c62 }, -+ { XFER_UDMA_0, 0x1c829c62 }, -+ -+ { XFER_MW_DMA_2, 0x2c829c62 }, -+ { XFER_MW_DMA_1, 0x2c829c66 }, -+ { XFER_MW_DMA_0, 0x2c829d2c }, -+ -+ { XFER_PIO_4, 0x0c829c62 }, -+ { XFER_PIO_3, 0x0c829c84 }, -+ { XFER_PIO_2, 0x0c829ca6 }, -+ { XFER_PIO_1, 0x0d029d26 }, -+ { XFER_PIO_0, 0x0d029d5e }, -+ { 0, 0x0d029d5e } -+}; -+ -+/** -+ * hpt3x2n_find_mode - reset the hpt3x2n bus -+ * @ap: ATA port -+ * @speed: transfer mode -+ * -+ * Return the 32bit register programming information for this channel -+ * that matches the speed provided. For the moment the clocks table -+ * is hard coded but easy to change. This will be needed if we use -+ * different DPLLs -+ */ -+ -+static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) -+{ -+ struct hpt_clock *clocks = hpt3x2n_clocks; -+ -+ while(clocks->xfer_speed) { -+ if(clocks->xfer_speed == speed) -+ return clocks->timing; -+ clocks++; -+ } -+ BUG(); -+} -+ -+/** -+ * hpt3x2n_phy_reset - reset the hpt3x2n bus -+ * @ap: ATA port to reset -+ * -+ * Perform the PHY reset handling for the 3x2N -+ */ -+ -+static void hpt3x2n_phy_reset(struct ata_port *ap) -+{ -+ u8 scr2, ata66; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_byte(pdev, 0x5B, &scr2); -+ pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01); -+ /* Cable register now active */ -+ pci_read_config_byte(pdev, 0x5A, &ata66); -+ /* Restore state */ -+ pci_write_config_byte(pdev, 0x5B, scr2); -+ -+ if(ata66 & (1 << ap->hard_port_no)) -+ ap->cbl = ATA_CBL_PATA40; -+ else -+ ap->cbl = ATA_CBL_PATA80; -+ -+ /* Reset the state machine */ -+ pci_write_config_byte(pdev, 0x50, 0x37); -+ pci_write_config_byte(pdev, 0x54, 0x37); -+ udelay(100); -+ -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+/** -+ * hpt3x2n_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Perform PIO mode setup. -+ */ -+ -+static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x07; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt3x2n_find_mode(ap, adev->pio_mode); -+ mode &= ~0x8000000; /* No FIFO in PIO */ -+ mode &= ~0x30070000; /* Leave config bits alone */ -+ reg &= 0x30070000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt3x2n_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * Set up the channel for MWDMA or UDMA modes. Much the same as with -+ * PIO, load the mode number and then set MWDMA or UDMA flag. -+ */ -+ -+static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x07; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt3x2n_find_mode(ap, adev->dma_mode); -+ mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ -+ mode &= ~0xC0000000; /* Leave config bits alone */ -+ reg &= 0xC0000000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt3x2n_bmdma_end - DMA engine stop -+ * @qc: ATA command -+ * -+ * Clean up after the HPT3x2n and later DMA engine -+ */ -+ -+static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int mscreg = 0x50 + 2 * ap->hard_port_no; -+ u8 bwsr_stat, msc_stat; -+ -+ pci_read_config_byte(pdev, 0x6A, &bwsr_stat); -+ pci_read_config_byte(pdev, mscreg, &msc_stat); -+ if(bwsr_stat & (1 << ap->hard_port_no)) -+ pci_write_config_byte(pdev, mscreg, msc_stat | 0x30); -+ ata_bmdma_stop(qc); -+} -+ -+/** -+ * hpt3x2n_set_clock - clock control -+ * @ap: ATA port -+ * @source: 0x21 or 0x23 for PLL or PCI sourced clock -+ * -+ * Switch the ATA bus clock between the PLL and PCI clock sources -+ * while correctly isolating the bus and resetting internal logic -+ * -+ * We must use the DPLL for -+ * - writing -+ * - second channel UDMA7 (SATA ports) or higher -+ * - 66MHz PCI -+ * -+ * or we will underclock the device and get reduced performance. -+ */ -+ -+static void hpt3x2n_set_clock(struct ata_port *ap, int source) -+{ -+ unsigned long bmdma = ap->ioaddr.bmdma_addr; -+ -+ /* Tristate the bus */ -+ outb(0x80, bmdma+0x73); -+ outb(0x80, bmdma+0x77); -+ -+ /* Switch clock and reset channels */ -+ outb(source, bmdma+0x7B); -+ outb(0xC0, bmdma+0x79); -+ -+ /* Reset state machines */ -+ outb(0x37, bmdma+0x70); -+ outb(0x37, bmdma+0x74); -+ -+ /* Complete reset */ -+ outb(0x00, bmdma+0x79); -+ -+ /* Reconnect channels to bus */ -+ outb(0x00, bmdma+0x73); -+ outb(0x00, bmdma+0x77); -+} -+ -+/* Check if our partner interface is busy */ -+ -+static int hpt3x2n_pair_idle(struct ata_port *ap) -+{ -+ struct ata_host_set *host = ap->host_set; -+ struct ata_port *pair = host->ports[ap->hard_port_no ^ 1]; -+ -+ if(pair->hsm_task_state == HSM_ST_IDLE) -+ return 1; -+ return 0; -+} -+ -+static int hpt3x2n_use_dpll(struct ata_port *ap, int reading) -+{ -+ long flags = (long)ap->host_set->private_data; -+ /* See if we should use the DPLL */ -+ if (reading == 0) -+ return USE_DPLL; /* Needed for write */ -+ if (flags & PCI66) -+ return USE_DPLL; /* Needed at 66Mhz */ -+ return 0; -+} -+ -+static int hpt3x2n_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_taskfile *tf = &qc->tf; -+ struct ata_port *ap = qc->ap; -+ int flags = (long)ap->host_set->private_data; -+ -+ if(hpt3x2n_pair_idle(ap)) { -+ int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE)); -+ if((flags & USE_DPLL) != dpll) { -+ if(dpll == 1) -+ hpt3x2n_set_clock(ap, 0x21); -+ else -+ hpt3x2n_set_clock(ap, 0x23); -+ } -+ } -+ return ata_qc_issue_prot(qc); -+} -+ -+static struct scsi_host_template hpt3x2n_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, -+// .ordered_flush = 1, -+}; -+/* -+ * Configuration for HPT3x2n. -+ */ -+ -+static struct ata_port_operations hpt3x2n_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt3x2n_set_piomode, -+ .set_dmamode = hpt3x2n_set_dmamode, -+ -+ .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 = hpt3x2n_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = hpt3x2n_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = hpt3x2n_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * hpt3xn_calibrate_dpll - Calibrate the DPLL loop -+ * @dev: PCI device -+ * -+ * Perform a calibration cycle on the HPT3xN DPLL. Returns 1 if this -+ * succeeds -+ */ -+ -+static int hpt3xn_calibrate_dpll(struct pci_dev *dev) -+{ -+ u8 reg5b; -+ u32 reg5c; -+ int tries; -+ -+ for(tries = 0; tries < 0x5000; tries++) { -+ udelay(50); -+ pci_read_config_byte(dev, 0x5b, ®5b); -+ if(reg5b & 0x80) { -+ /* See if it stays set */ -+ for(tries = 0; tries < 0x1000; tries ++) { -+ pci_read_config_byte(dev, 0x5b, ®5b); -+ /* Failed ? */ -+ if((reg5b & 0x80) == 0) -+ return 0; -+ } -+ /* Turn off tuning, we have the DPLL set */ -+ pci_read_config_dword(dev, 0x5c, ®5c); -+ pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100); -+ return 1; -+ } -+ } -+ /* Never went stable */ -+ return 0; -+} -+ -+static int hpt3x2n_pci_clock(struct pci_dev *pdev) -+{ -+ unsigned long freq; -+ u32 fcnt; -+ -+ pci_read_config_dword(pdev, 0x70/*CHECKME*/, &fcnt); -+ if((fcnt >> 12) != 0xABCDE) { -+ printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n"); -+ return 33; /* Not BIOS set */ -+ } -+ fcnt &= 0x1FF; -+ -+ freq = (fcnt * 77) / 192; -+ -+ /* Clamp to bands */ -+ if(freq < 40) -+ return 33; -+ if(freq < 45) -+ return 40; -+ if(freq < 55) -+ return 50; -+ return 66; -+} -+ -+/** -+ * hpt3x2n_init_one - Initialise an HPT37X/302 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Initialise an HPT3x2n device. There are some interesting complications -+ * here. Firstly the chip may report 366 and be one of several variants. -+ * Secondly all the timings depend on the clock for the chip which we must -+ * detect and look up -+ * -+ * This is the known chip mappings. It may be missing a couple of later -+ * releases. -+ * -+ * Chip version PCI Rev Notes -+ * HPT372 4 (HPT366) 5 Other driver -+ * HPT372N 4 (HPT366) 6 UDMA133 -+ * HPT372 5 (HPT372) 1 Other driver -+ * HPT372N 5 (HPT372) 2 UDMA133 -+ * HPT302 6 (HPT302) * Other driver -+ * HPT302N 6 (HPT302) > 1 UDMA133 -+ * HPT371 7 (HPT371) * Other driver -+ * HPT371N 7 (HPT371) > 1 UDMA133 -+ * HPT374 8 (HPT374) * Other driver -+ * HPT372N 9 (HPT372N) * UDMA133 -+ * -+ * (1) UDMA133 support depends on the bus clock -+ * -+ * To pin down HPT371N -+ */ -+ -+static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ /* HPT372N and friends - UDMA133 */ -+ static struct ata_port_info info = { -+ .sht = &hpt3x2n_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &hpt3x2n_port_ops -+ }; -+ struct ata_port_info *port_info[2]; -+ struct ata_port_info *port = &info; -+ -+ u8 irqmask; -+ u32 class_rev; -+ -+ unsigned int pci_mhz; -+ unsigned int f_low, f_high; -+ int adjust; -+ -+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); -+ class_rev &= 0xFF; -+ -+ switch(dev->device) { -+ case PCI_DEVICE_ID_TTI_HPT366: -+ if(class_rev < 6) -+ return -ENODEV; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT372: -+ /* 372N if rev >= 1*/ -+ if(class_rev == 0) -+ return -ENODEV; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT302: -+ if(class_rev < 2) -+ return -ENODEV; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT372N: -+ break; -+ default: -+ printk(KERN_ERR "pata_hpt3x2n: PCI table is bogus please report (%d).\n", dev->device); -+ return -ENODEV; -+ } -+ -+ /* Ok so this is a chip we support */ -+ -+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); -+ pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); -+ pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); -+ -+ pci_read_config_byte(dev, 0x5A, &irqmask); -+ irqmask &= ~0x10; -+ pci_write_config_byte(dev, 0x5a, irqmask); -+ -+ /* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or -+ 50 for UDMA100. Right now we always use 66 */ -+ -+ pci_mhz = hpt3x2n_pci_clock(dev); -+ -+ f_low = (pci_mhz * 48) / 66; /* PCI Mhz for 66Mhz DPLL */ -+ f_high = f_low + 2; /* Tolerance */ -+ -+ pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100); -+ /* PLL clock */ -+ pci_write_config_byte(dev, 0x5B, 0x21); -+ -+ /* Unlike the 37x we don't try jiggling the frequency */ -+ for(adjust = 0; adjust < 8; adjust++) { -+ if(hpt3xn_calibrate_dpll(dev)) -+ break; -+ pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); -+ } -+ if(adjust == 8) -+ printk(KERN_WARNING "hpt3xn: DPLL did not stabilize.\n"); -+ -+ /* Set our private data up. We only need a few flags so we use -+ it directly */ -+ port->private_data = NULL; -+ if(pci_mhz > 60) -+ port->private_data = (void *)PCI66; -+ -+ /* Now kick off ATA set up */ -+ port_info[0] = port_info[1] = port; -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id hpt3x2n[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372N), }, -+ { 0, }, -+}; -+ -+static struct pci_driver hpt3x2n_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = hpt3x2n, -+ .probe = hpt3x2n_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init hpt3x2n_init(void) -+{ -+ return pci_register_driver(&hpt3x2n_pci_driver); -+} -+ -+ -+static void __exit hpt3x2n_exit(void) -+{ -+ pci_unregister_driver(&hpt3x2n_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3x2n/30x"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, hpt3x2n); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(hpt3x2n_init); -+module_exit(hpt3x2n_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_isapnp.c linux-2.6.16-rc2/drivers/scsi/pata_isapnp.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_isapnp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_isapnp.c 2006-01-21 16:52:31.000000000 +0000 -@@ -0,0 +1,151 @@ -+ -+/* -+ * pata-isapnp.c - ISA PnP PATA controller driver. -+ * Copyright 2005/2006 Red Hat Inc <alan@redhat.com>, all rights reserved. -+ * -+ * Based in part on ide-pnp.c by Andrey Panin <pazke@donpac.ru> -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/isapnp.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/ata.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_isapnp" -+#define DRV_VERSION "0.1" -+ -+static struct scsi_host_template isapnp_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations isapnp_port_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, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * isapnp_init_one - attach an isapnp interface -+ * @idev: PnP device -+ * @dev_id: matching detect line -+ * -+ * Register an ISA bus IDE interface. Such interfaces are PIO 0 and -+ * non shared IRQ. -+ */ -+ -+static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev_id) -+{ -+ struct ata_probe_ent ae; -+ -+ if (pnp_port_valid(idev, 0) == 0) -+ return -ENODEV; -+ if (pnp_port_valid(idev, 1) == 0) -+ return -ENODEV; -+ -+ /* FIXME: Should selected polled PIO here not fail */ -+ if (pnp_irq_valid(idev, 0) == 0) -+ return -ENODEV; -+ -+ memset(&ae, 0, sizeof(struct ata_probe_ent)); -+ INIT_LIST_HEAD(&ae.node); -+ ae.dev = &idev->dev; -+ ae.port_ops = &isapnp_port_ops; -+ ae.sht = &isapnp_sht; -+ ae.n_ports = 1; -+ ae.pio_mask = 1; /* ISA so PIO 0 cycles */ -+ ae.irq = pnp_irq(idev, 0); -+ ae.irq_flags = 0; -+ ae.host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_IRQ_MASK; -+ ae.port[0].cmd_addr = pnp_port_start(idev, 0); -+ ae.port[0].altstatus_addr = pnp_port_start(idev, 1); -+ ae.port[0].ctl_addr = pnp_port_start(idev, 1); -+ ata_std_ports(&ae.port[0]); -+ -+ if (ata_device_add(&ae) == 0) -+ return -ENODEV; -+ return 0; -+} -+ -+/** -+ * isapnp_remove_one - unplug an isapnp interface -+ * @idev: PnP device -+ * -+ * Remove a previously configured PnP ATA port. Called only on module -+ * unload events as the core does not currently deal with ISAPnP docking. -+ */ -+ -+static void isapnp_remove_one(struct pnp_dev *idev) -+{ -+ struct device *dev = &idev->dev; -+ struct ata_host_set *host_set = dev_get_drvdata(dev); -+ -+ ata_host_set_remove(host_set); -+ dev_set_drvdata(dev, NULL); -+} -+ -+static struct pnp_device_id isapnp_devices[] = { -+ /* Generic ESDI/IDE/ATA compatible hard disk controller */ -+ {.id = "PNP0600", .driver_data = 0}, -+ {.id = ""} -+}; -+ -+static struct pnp_driver isapnp_driver = { -+ .name = DRV_NAME, -+ .id_table = isapnp_devices, -+ .probe = isapnp_init_one, -+ .remove = isapnp_remove_one, -+}; -+ -+static int __init isapnp_init(void) -+{ -+ return pnp_register_driver(&isapnp_driver); -+} -+ -+static void __exit isapnp_exit(void) -+{ -+ pnp_unregister_driver(&isapnp_driver); -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for ISA PnP ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(isapnp_init); -+module_exit(isapnp_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_it8172.c linux-2.6.16-rc2/drivers/scsi/pata_it8172.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_it8172.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_it8172.c 2006-02-07 13:40:09.935160856 +0000 -@@ -0,0 +1,280 @@ -+/* -+ * pata_it8172.c - IT8172 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based heavily on -+ * -+ * BRIEF MODULE DESCRIPTION -+ * IT8172 IDE controller support -+ * -+ * Copyright 2000 MontaVista Software Inc. -+ * Author: MontaVista Software, Inc. -+ * stevel@mvista.com or source@mvista.com -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ * TODO -+ * Check for errata -+ * See if we really need to force native mode -+ * PIO timings (also lacking in original) -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "it8172" -+#define DRV_VERSION "0.1.1" -+ -+static void it8172_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits it8172_enable_bits[] = { -+ { 0x00, 0, 0x00, 0x00 }, -+ { 0x40, 1, 0x00, 0x01 } -+ }; -+ -+ if (ap->hard_port_no && !pci_test_config_bits(pdev, &it8172_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * it8172_set_pio_timing - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called by both the pio and dma setup functions to set the controller -+ * timings for PIO transfers. We must load both the mode number and -+ * timing values into the controller. -+ */ -+ -+static void it8172_set_pio_timing(struct ata_port *ap, struct ata_device *adev, int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u16 reg40; -+ -+ pci_read_config_word(pdev, 0x40, ®40); -+ -+ /* -+ * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44 -+ * are being left at the default values of 8 PCI clocks (242 nsec -+ * for a 33 MHz clock). These can be safely shortened at higher -+ * PIO modes. The DIOR/DIOW pulse width and recovery times only -+ * apply to PIO modes, not to the DMA modes. -+ */ -+ -+ /* -+ * Enable port 0x44. The IT8172G spec is confused; it calls -+ * this register the "Slave IDE Timing Register", but in fact, -+ * it controls timing for both master and slave drives. -+ */ -+ -+ reg40 |= 0x4000; -+ if(adev->devno) { -+ reg40 |= 0xC006; -+ if(pio > 1) -+ /* Enable prefetch and IORDY sample-point */ -+ reg40 |= 0x0060; -+ } else { -+ reg40 |= 0xC060; -+ if(pio > 1) -+ /* Enable prefetch and IORDY sample-point */ -+ reg40 |= 0x0006; -+ } -+ /* Write back the enables */ -+ pci_write_config_word(pdev, 0x40, reg40); -+} -+ -+/** -+ * it8172_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. We use a shared helper for this -+ * as the DMA setup must also adjust the PIO timing information. -+ */ -+ -+static void it8172_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ it8172_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0); -+} -+ -+/** -+ * it8172_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the DMA mode setup. We must tune an appropriate PIO -+ * mode to match. -+ */ -+ -+static void it8172_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = (2 * ap->hard_port_no) + adev->devno; -+ u8 reg48, reg4a; -+ int pio; -+ -+ static int pio_map[] = { 1, 3, 4}; -+ /* -+ * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec -+ * at 33 MHz PCI clock) seems to cause BadCRC errors during DMA -+ * transfers on some drives, even though both numbers meet the minimum -+ * ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively. -+ * So the faster times are just commented out here. The good news is -+ * that the slower cycle time has very little affect on transfer -+ * performance. -+ */ -+ -+ pci_read_config_byte(pdev, 0x48, ®48); -+ pci_read_config_byte(pdev, 0x4A, ®4a); -+ -+ reg4a &= ~(3 << (4 * dn)); -+ -+ if(adev->dma_mode >= XFER_UDMA_0) { -+ reg48 |= 1 << dn; -+#ifdef UDMA_TIMING_SET -+ reg4a |= ((adev->dma_mode - XFER_UDMA_0) << (4 * dn)); -+#endif -+ pio = 4; -+ } else { -+ pio = pio_map[adev->dma_mode - XFER_MW_DMA_0]; -+ reg48 &= ~ (1 << dn); -+ } -+ pci_write_config_byte(pdev, 0x48, reg48); -+ pci_write_config_byte(pdev, 0x4A, reg4a); -+ it8172_set_pio_timing(ap, adev, pio); -+ -+} -+ -+static struct scsi_host_template it8172_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations it8172_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = it8172_set_piomode, -+ .set_dmamode = it8172_set_dmamode, -+ .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 = it8172_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &it8172_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x06, /* No MWDMA0 support */ -+ .udma_mask = 0x7, -+ .port_ops = &it8172_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ if ((!(PCI_FUNC(dev->devfn) & 1) || -+ (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))) -+ return -ENODEV; /* IT8172 is more than an IDE controller */ -+ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id it8172[] = { -+ { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0, }, -+}; -+ -+static struct pci_driver it8172_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = it8172, -+ .probe = it8172_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init it8172_init(void) -+{ -+ return pci_register_driver(&it8172_pci_driver); -+} -+ -+ -+static void __exit it8172_exit(void) -+{ -+ pci_unregister_driver(&it8172_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for ITE IT8172"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, it8172); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(it8172_init); -+module_exit(it8172_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_it821x.c linux-2.6.16-rc2/drivers/scsi/pata_it821x.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_it821x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_it821x.c 2006-02-07 13:41:20.868377368 +0000 -@@ -0,0 +1,741 @@ -+/* -+ * ata-it821x.c - IT821x PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon -+ * -+ * it821x.c -+ * -+ * linux/drivers/ide/pci/it821x.c Version 0.09 December 2004 -+ * -+ * Copyright (C) 2004 Red Hat <alan@redhat.com> -+ * -+ * May be copied or modified under the terms of the GNU General Public License -+ * Based in part on the ITE vendor provided SCSI driver. -+ * -+ * Documentation available from -+ * http://www.ite.com.tw/pc/IT8212F_V04.pdf -+ * Some other documents are NDA. -+ * -+ * The ITE8212 isn't exactly a standard IDE controller. It has two -+ * modes. In pass through mode then it is an IDE controller. In its smart -+ * mode its actually quite a capable hardware raid controller disguised -+ * as an IDE controller. Smart mode only understands DMA read/write and -+ * identify, none of the fancier commands apply. The IT8211 is identical -+ * in other respects but lacks the raid mode. -+ * -+ * Errata: -+ * o Rev 0x10 also requires master/slave hold the same DMA timings and -+ * cannot do ATAPI MWDMA. -+ * o The identify data for raid volumes lacks CHS info (technically ok) -+ * but also fails to set the LBA28 and other bits. We fix these in -+ * the IDE probe quirk code. -+ * o If you write LBA48 sized I/O's (ie > 256 sector) in smart mode -+ * raid then the controller firmware dies -+ * o Smart mode without RAID doesn't clear all the necessary identify -+ * bits to reduce the command set to the one used -+ * -+ * This has a few impacts on the driver -+ * - In pass through mode we do all the work you would expect -+ * - In smart mode the clocking set up is done by the controller generally -+ * but we must watch the other limits and filter. -+ * - There are a few extra vendor commands that actually talk to the -+ * controller but only work PIO with no IRQ. -+ * -+ * Vendor areas of the identify block in smart mode are used for the -+ * timing and policy set up. Each HDD in raid mode also has a serial -+ * block on the disk. The hardware extra commands are get/set chip status, -+ * rebuild, get rebuild status. -+ * -+ * In Linux the driver supports pass through mode as if the device was -+ * just another IDE controller. If the smart mode is running then -+ * volumes are managed by the controller firmware and each IDE "disk" -+ * is a raid volume. Even more cute - the controller can do automated -+ * hotplug and rebuild. -+ * -+ * The pass through controller itself is a little demented. It has a -+ * flaw that it has a single set of PIO/MWDMA timings per channel so -+ * non UDMA devices restrict each others performance. It also has a -+ * single clock source per channel so mixed UDMA100/133 performance -+ * isn't perfect and we have to pick a clock. Thankfully none of this -+ * matters in smart mode. ATAPI DMA is not currently supported. -+ * -+ * It seems the smart mode is a win for RAID1/RAID10 but otherwise not. -+ * -+ * TODO -+ * - ATAPI and other speed filtering -+ * - Command filter in smart mode -+ * - RAID configuration ioctls -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+ -+#define DRV_NAME "it821x" -+#define DRV_VERSION "0.2" -+ -+struct it821x_dev -+{ -+ unsigned int smart:1, /* Are we in smart raid mode */ -+ timing10:1; /* Rev 0x10 */ -+ u8 clock_mode; /* 0, ATA_50 or ATA_66 */ -+ u8 want[2][2]; /* Mode/Pri log for master slave */ -+ /* We need these for switching the clock when DMA goes on/off -+ The high byte is the 66Mhz timing */ -+ u16 pio[2]; /* Cached PIO values */ -+ u16 mwdma[2]; /* Cached MWDMA values */ -+ u16 udma[2]; /* Cached UDMA values (per drive) */ -+ u16 last_device; /* Master or slave loaded ? */ -+}; -+ -+#define ATA_66 0 -+#define ATA_50 1 -+#define ATA_ANY 2 -+ -+#define UDMA_OFF 0 -+#define MWDMA_OFF 0 -+ -+/* -+ * We allow users to force the card into non raid mode without -+ * flashing the alternative BIOS. This is also neccessary right now -+ * for embedded platforms that cannot run a PC BIOS but are using this -+ * device. -+ */ -+ -+static int it8212_noraid; -+ -+ -+/** -+ * it821x_phy_reset - probe/reset -+ * @ap: ATA port -+ * -+ * Set the cable type and trigger a probe -+ */ -+ -+static void it821x_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA80; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * it821x_program - program the PIO/MWDMA registers -+ * @ap: ATA port -+ * @adev: Device to program -+ * @timing: Timing value (66Mhz in top 8bits, 50 in the low 8) -+ * -+ * Program the PIO/MWDMA timing for this channel according to the -+ * current clock. These share the same register so are managed by -+ * the DMA start/stop sequence as with the old driver. -+ */ -+ -+static void it821x_program(struct ata_port *ap, struct ata_device *adev, u16 timing) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct it821x_dev *itdev = ap->private_data; -+ int channel = ap->hard_port_no; -+ u8 conf; -+ -+ /* Program PIO/MWDMA timing bits */ -+ if(itdev->clock_mode == ATA_66) -+ conf = timing >> 8; -+ else -+ conf = timing & 0xFF; -+ pci_write_config_byte(pdev, 0x54 + 4 * channel, conf); -+} -+ -+ -+/** -+ * it821x_program_udma - program the UDMA registers -+ * @ap: ATA port -+ * @adev: ATA device to update -+ * @timing: Timing bits. Top 8 are for 66Mhz bottom for 50Mhz -+ * -+ * Program the UDMA timing for this drive according to the -+ * current clock. Handles the dual clocks and also knows about -+ * the errata on the 0x10 revision. The UDMA errata is partly handled -+ * here and partly in start_dma. -+ */ -+ -+static void it821x_program_udma(struct ata_port *ap, struct ata_device *adev, u16 timing) -+{ -+ struct it821x_dev *itdev = ap->private_data; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int channel = ap->hard_port_no; -+ int unit = adev->devno; -+ u8 conf; -+ -+ /* Program UDMA timing bits */ -+ if(itdev->clock_mode == ATA_66) -+ conf = timing >> 8; -+ else -+ conf = timing & 0xFF; -+ if(itdev->timing10 == 0) -+ pci_write_config_byte(pdev, 0x56 + 4 * channel + unit, conf); -+ else { -+ /* Early revision must be programmed for both together */ -+ pci_write_config_byte(pdev, 0x56 + 4 * channel, conf); -+ pci_write_config_byte(pdev, 0x56 + 4 * channel + 1, conf); -+ } -+} -+ -+/** -+ * it821x_clock_strategy -+ * @ap: ATA interface -+ * @adev: ATA device being updated -+ * -+ * Select between the 50 and 66Mhz base clocks to get the best -+ * results for this interface. -+ */ -+ -+static void it821x_clock_strategy(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct it821x_dev *itdev = ap->private_data; -+ u8 unit = adev->devno; -+ struct ata_device *pair = &ap->device[1-unit]; -+ -+ int clock, altclock; -+ u8 v; -+ int sel = 0; -+ -+ /* Look for the most wanted clocking */ -+ if(itdev->want[0][0] > itdev->want[1][0]) { -+ clock = itdev->want[0][1]; -+ altclock = itdev->want[1][1]; -+ } else { -+ clock = itdev->want[1][1]; -+ altclock = itdev->want[0][1]; -+ } -+ -+ /* Master doesn't care does the slave ? */ -+ if(clock == ATA_ANY) -+ clock = altclock; -+ -+ /* Nobody cares - keep the same clock */ -+ if(clock == ATA_ANY) -+ return; -+ /* No change */ -+ if(clock == itdev->clock_mode) -+ return; -+ -+ /* Load this into the controller ? */ -+ if(clock == ATA_66) -+ itdev->clock_mode = ATA_66; -+ else { -+ itdev->clock_mode = ATA_50; -+ sel = 1; -+ } -+ pci_read_config_byte(pdev, 0x50, &v); -+ v &= ~(1 << (1 + ap->hard_port_no)); -+ v |= sel << (1 + ap->hard_port_no); -+ pci_write_config_byte(pdev, 0x50, v); -+ -+ /* -+ * Reprogram the UDMA/PIO of the pair drive for the switch -+ * MWDMA will be dealt with by the dma switcher -+ */ -+ if(pair && itdev->udma[1-unit] != UDMA_OFF) { -+ it821x_program_udma(ap, pair, itdev->udma[1-unit]); -+ it821x_program(ap, pair, itdev->pio[1-unit]); -+ } -+ /* -+ * Reprogram the UDMA/PIO of our drive for the switch. -+ * MWDMA will be dealt with by the dma switcher -+ */ -+ if(itdev->udma[unit] != UDMA_OFF) { -+ it821x_program_udma(ap, adev, itdev->udma[unit]); -+ it821x_program(ap, adev, itdev->pio[unit]); -+ } -+} -+ -+/** -+ * it821x_passthru_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Configure for PIO mode. This is complicated as the register is -+ * shared by PIO and MWDMA and for both channels. -+ */ -+ -+static void it821x_passthru_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ /* Spec says 89 ref driver uses 88 */ -+ static u16 pio[] = { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 }; -+ static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY }; -+ -+ struct it821x_dev *itdev = ap->private_data; -+ int unit = adev->devno; -+ int mode_wanted = adev->pio_mode - XFER_PIO_0; -+ -+ /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */ -+ itdev->want[unit][1] = pio_want[mode_wanted]; -+ itdev->want[unit][0] = 1; /* PIO is lowest priority */ -+ itdev->pio[unit] = pio[mode_wanted]; -+ it821x_clock_strategy(ap, adev); -+ it821x_program(ap, adev, itdev->pio[unit]); -+} -+ -+/** -+ * it821x_passthru_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Set up the DMA modes. The actions taken depend heavily on the mode -+ * to use. If UDMA is used as is hopefully the usual case then the -+ * timing register is private and we need only consider the clock. If -+ * we are using MWDMA then we have to manage the setting ourself as -+ * we switch devices and mode. -+ */ -+ -+static void it821x_passthru_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u16 dma[] = { 0x8866, 0x3222, 0x3121 }; -+ static u8 mwdma_want[] = { ATA_ANY, ATA_66, ATA_ANY }; -+ static u16 udma[] = { 0x4433, 0x4231, 0x3121, 0x2121, 0x1111, 0x2211, 0x1111 }; -+ static u8 udma_want[] = { ATA_ANY, ATA_50, ATA_ANY, ATA_66, ATA_66, ATA_50, ATA_66 }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct it821x_dev *itdev = ap->private_data; -+ int channel = ap->hard_port_no; -+ int unit = adev->devno; -+ u8 conf; -+ -+ if(adev->dma_mode >= XFER_UDMA_0) { -+ int mode_wanted = adev->dma_mode - XFER_UDMA_0; -+ -+ itdev->want[unit][1] = udma_want[mode_wanted]; -+ itdev->want[unit][0] = 3; /* UDMA is high priority */ -+ itdev->mwdma[unit] = MWDMA_OFF; -+ itdev->udma[unit] = udma[mode_wanted]; -+ if(mode_wanted >= 5) -+ itdev->udma[unit] |= 0x8080; /* UDMA 5/6 select on */ -+ -+ /* UDMA on. Again revision 0x10 must do the pair */ -+ pci_read_config_byte(pdev, 0x50, &conf); -+ if(itdev->timing10) -+ conf &= channel ? 0x9F: 0xE7; -+ else -+ conf &= ~ (1 << (3 + 2 * channel + unit)); -+ pci_write_config_byte(pdev, 0x50, conf); -+ it821x_clock_strategy(ap, adev); -+ it821x_program_udma(ap, adev, itdev->udma[unit]); -+ } else { -+ int mode_wanted = adev->dma_mode - XFER_UDMA_0; -+ -+ itdev->want[unit][1] = mwdma_want[mode_wanted]; -+ itdev->want[unit][0] = 2; /* MWDMA is low priority */ -+ itdev->mwdma[unit] = dma[mode_wanted]; -+ itdev->udma[unit] = UDMA_OFF; -+ -+ /* UDMA bits off - Revision 0x10 do them in pairs */ -+ pci_read_config_byte(pdev, 0x50, &conf); -+ if(itdev->timing10) -+ conf |= channel ? 0x60: 0x18; -+ else -+ conf |= 1 << (3 + 2 * channel + unit); -+ pci_write_config_byte(pdev, 0x50, conf); -+ it821x_clock_strategy(ap, adev); -+ } -+} -+ -+/** -+ * it821x_passthru_dma_start - DMA start callback -+ * @qc: Command in progress -+ * -+ * Usually drivers set the DMA timing at the point the set_dmamode call -+ * is made. IT821x however requires we load new timings on the -+ * transitions in some cases. -+ */ -+ -+static void it821x_passthru_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ struct it821x_dev *itdev = ap->private_data; -+ int unit = adev->devno; -+ -+ if(itdev->mwdma[unit] != MWDMA_OFF) -+ it821x_program(ap, adev, itdev->mwdma[unit]); -+ else if(itdev->udma[unit] != UDMA_OFF && itdev->timing10) -+ it821x_program_udma(ap, adev, itdev->udma[unit]); -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * it821x_passthru_dma_stop - DMA stop callback -+ * @qc: ATA command -+ * -+ * We loaded new timings in dma_start, as a result we need to restore -+ * the PIO timings in dma_stop so that the next command issue gets the -+ * right clock values. -+ */ -+ -+static void it821x_passthru_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ struct it821x_dev *itdev = ap->private_data; -+ int unit = adev->devno; -+ -+ ata_bmdma_stop(qc); -+ if(itdev->mwdma[unit] != MWDMA_OFF) -+ it821x_program(ap, adev, itdev->pio[unit]); -+} -+ -+ -+/** -+ * it821x_passthru_dev_select - Select master/slave -+ * @ap: ATA port -+ * @device: Device number (not pointer) -+ * -+ * Device selection hook. If neccessary perform clock switching -+ */ -+ -+void it821x_passthru_dev_select(struct ata_port *ap, unsigned int device) -+{ -+ struct it821x_dev *itdev = ap->private_data; -+ if(itdev && device != itdev->last_device) { -+ struct ata_device *adev = &ap->device[device]; -+ it821x_program(ap, adev, itdev->pio[adev->devno]); -+ itdev->last_device = device; -+ } -+} -+ -+/** -+ * it821x_passthru_qc_issue_prot - wrap qc issue prot -+ * @qc: command -+ * -+ * Wrap the command issue sequence for the IT821x. We need to -+ * perform out own device selection timing loads before the -+ * usual happenings kick off -+ */ -+ -+static int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ it821x_passthru_dev_select(qc->ap, qc->dev->devno); -+ return ata_qc_issue_prot(qc); -+} -+ -+/** -+ * it821x_smart_set_mode - mode setting -+ * @ap: interface to set up -+ * -+ * Use a non standard set_mode function. We don't want to be tuned. -+ * The BIOS configured everything. Our job is not to fiddle. We -+ * read the dma enabled bits from the PCI configuration of the device -+ * and respect them. -+ */ -+ -+static void it821x_smart_set_mode(struct ata_port *ap) -+{ -+ int dma_enabled; -+ int i; -+ -+ /* Bits 5 and 6 indicate if DMA is active on master/slave */ -+ dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *dev = &ap->device[i]; -+ if (ata_dev_present(dev)) { -+ /* We don't really care */ -+ dev->pio_mode = XFER_PIO_0; -+ dev->dma_mode = XFER_MW_DMA_0; -+ /* We do need the right mode information for DMA or PIO -+ and this comes from the current configuration flags */ -+ if(dma_enabled & (1 << (5 + i))) { -+ dev->xfer_mode = XFER_MW_DMA_0; -+ dev->xfer_shift = ATA_SHIFT_MWDMA; -+ dev->flags &= ~ATA_DFLAG_PIO; -+ } else { -+ dev->xfer_mode = XFER_PIO_0; -+ dev->xfer_shift = ATA_SHIFT_PIO; -+ dev->flags |= ATA_DFLAG_PIO; -+ } -+ /* Keep sector count safe (LBA48 counts blow the -+ brains of the firmware) */ -+ dev->flags |= ATA_DFLAG_LOCK_SECTORS; -+ } -+ } -+} -+ -+/** -+ * it821x_check_atapi_dma - ATAPI DMA handler -+ * @qc: Command we are about to issue -+ * -+ * Decide if this ATAPI command can be issued by DMA on this -+ * controller. Return 0 if it can be. -+ */ -+ -+static int it821x_check_atapi_dma(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct it821x_dev *itdev = ap->private_data; -+ -+ /* No ATAPI DMA in smart mode */ -+ if(itdev->smart) -+ return -EOPNOTSUPP; -+ /* No ATAPI DMA on rev 10 */ -+ if(itdev->timing10) -+ return -EOPNOTSUPP; -+ /* Cool */ -+ return 0; -+} -+ -+ -+/** -+ * it821x_port_start - port setup -+ * @ap: ATA port being set up -+ * -+ * The it821x needs to maintain private data structures and also to -+ * use the standard PCI interface which lacks support for this -+ * functionality. We instead set up the private data on the port -+ * start hook, and tear it down on port stop -+ */ -+ -+static int it821x_port_start(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct it821x_dev *itdev; -+ u8 conf; -+ -+ int ret = ata_port_start(ap); -+ if(ret < 0) -+ return ret; -+ -+ ap->private_data = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL); -+ if(ap->private_data == NULL) { -+ ata_port_stop(ap); -+ return -ENOMEM; -+ } -+ -+ itdev = ap->private_data; -+ memset(itdev, 0, sizeof(struct it821x_dev)); -+ -+ pci_read_config_byte(pdev, 0x50, &conf); -+ -+ if(conf & 1) { -+ itdev->smart = 1; -+ /* Long I/O's although allowed in LBA48 space cause the -+ onboard firmware to enter the twighlight zone */ -+ /* No ATAPI DMA in this mode either */ -+ } -+ /* Pull the current clocks from 0x50 */ -+ if (conf & (1 << (1 + ap->hard_port_no))) -+ itdev->clock_mode = ATA_50; -+ else -+ itdev->clock_mode = ATA_66; -+ -+ itdev->want[0][1] = ATA_ANY; -+ itdev->want[1][1] = ATA_ANY; -+ itdev->last_device = -1; -+ -+ pci_read_config_byte(pdev, PCI_REVISION_ID, &conf); -+ if(conf == 0x10) { -+ itdev->timing10 = 1; -+ /* Need to disable ATAPI DMA for this case */ -+ if(!itdev->smart) -+ printk(KERN_WARNING DRV_NAME": Revision 0x10, workarounds activated.\n"); -+ } -+ -+ return 0; -+} -+ -+/** -+ * it821x_port_stop - port shutdown -+ * @ap: ATA port being removed -+ * -+ * Release the private objects we added in it821x_port_start -+ */ -+ -+static void it821x_port_stop(struct ata_port *ap) { -+ kfree(ap->private_data); -+ ap->private_data = NULL; /* We want an OOPS if we reuse this -+ too late! */ -+ ata_port_stop(ap); -+} -+ -+static struct scsi_host_template it821x_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, -+ /* 255 sectors to begin with. This is locked in smart mode but not -+ in pass through */ -+ .max_sectors = 255, -+ .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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations it821x_smart_port_ops = { -+ .set_mode = it821x_smart_set_mode, -+ .port_disable = ata_port_disable, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .check_atapi_dma= it821x_check_atapi_dma, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = it821x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = it821x_port_start, -+ .port_stop = it821x_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations it821x_passthru_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = it821x_passthru_set_piomode, -+ .set_dmamode = it821x_passthru_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .check_atapi_dma= it821x_check_atapi_dma, -+ .dev_select = it821x_passthru_dev_select, -+ -+ .phy_reset = it821x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = it821x_passthru_bmdma_start, -+ .bmdma_stop = it821x_passthru_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = it821x_passthru_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ .irq_handler = ata_interrupt, -+ .port_start = it821x_port_start, -+ .port_stop = it821x_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static void __devinit it821x_disable_raid(struct pci_dev *pdev) -+{ -+ /* Reset local CPU, and set BIOS not ready */ -+ pci_write_config_byte(pdev, 0x5E, 0x01); -+ -+ /* Set to bypass mode, and reset PCI bus */ -+ pci_write_config_byte(pdev, 0x50, 0x00); -+ pci_write_config_word(pdev, PCI_COMMAND, -+ PCI_COMMAND_PARITY | PCI_COMMAND_IO | -+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); -+ pci_write_config_word(pdev, 0x40, 0xA0F3); -+ -+ pci_write_config_dword(pdev,0x4C, 0x02040204); -+ pci_write_config_byte(pdev, 0x42, 0x36); -+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0); -+} -+ -+ -+static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ u8 conf; -+ -+ static struct ata_port_info info_smart = { -+ .sht = &it821x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &it821x_smart_port_ops -+ }; -+ static struct ata_port_info info_passthru = { -+ .sht = &it821x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &it821x_passthru_port_ops -+ }; -+ static struct ata_port_info *port_info[2]; -+ -+ static char *mode[2] = { "pass through", "smart" }; -+ -+ /* Force the card into bypass mode if so requested */ -+ if (it8212_noraid) { -+ printk(KERN_INFO DRV_NAME ": forcing bypass mode.\n"); -+ it821x_disable_raid(pdev); -+ } -+ pci_read_config_byte(pdev, 0x50, &conf); -+ conf &= 1; -+ -+ printk(KERN_INFO DRV_NAME ": controller in %s mode.\n", mode[conf]); -+ if(conf == 0) -+ port_info[0] = port_info[1] = &info_passthru; -+ else -+ port_info[0] = port_info[1] = &info_smart; -+ -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static struct pci_device_id it821x[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8211), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212), }, -+ { 0, }, -+}; -+ -+static struct pci_driver it821x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = it821x, -+ .probe = it821x_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init it821x_init(void) -+{ -+ return pci_register_driver(&it821x_pci_driver); -+} -+ -+ -+static void __exit it821x_exit(void) -+{ -+ pci_unregister_driver(&it821x_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the IT8211/IT8212 IDE RAID controller"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, it821x); -+MODULE_VERSION(DRV_VERSION); -+ -+ -+module_param_named(noraid, it8212_noraid, int, S_IRUGO); -+MODULE_PARM_DESC(it8212_noraid, "Force card into bypass mode"); -+ -+module_init(it821x_init); -+module_exit(it821x_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_legacy.c linux-2.6.16-rc2/drivers/scsi/pata_legacy.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_legacy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_legacy.c 2006-02-07 11:44:14.578535784 +0000 -@@ -0,0 +1,668 @@ -+ -+/* -+ * pata-legacy.c - Legacy port PATA/SATA controller driver. -+ * Copyright 2005/2006 Red Hat Inc <alan@redhat.com>, all rights reserved. -+ * -+ * An ATA driver for the legacy ATA ports. -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/ata.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "legacy" -+#define DRV_VERSION "0.3" -+ -+#define NR_HOST 6 -+ -+static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 }; -+static int legacy_irq[NR_HOST] = { 15, 14, 11, 10, 8, 12 }; -+ -+static struct ata_host_set *legacy_host[NR_HOST]; -+static int nr_legacy_host; -+static int legacy_all; -+static int ht6560a; -+static int ht6560b; -+static int opti82c611a; -+ -+/** -+ * legacy_set_mode - mode setting -+ * @ap: IDE interface -+ * -+ * Use a non standard set_mode function. We don't want to be tuned. -+ * -+ * The BIOS configured everything. Our job is not to fiddle. Just use -+ * whatever PIO the hardware is using and leave it at that. When we -+ * get some kind of nice user driven API for control then we can -+ * expand on this as per hdparm in the base kernel. -+ */ -+ -+static void legacy_set_mode(struct ata_port *ap) -+{ -+ int i; -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *dev = &ap->device[i]; -+ if (ata_dev_present(dev)) { -+ dev->pio_mode = XFER_PIO_0; -+ dev->xfer_mode = XFER_PIO_0; -+ dev->xfer_shift = ATA_SHIFT_PIO; -+ dev->flags |= ATA_DFLAG_PIO; -+ } -+ } -+} -+ -+static struct scsi_host_template legacy_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations legacy_port_ops = { -+ .set_mode = legacy_set_mode, -+ -+ .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, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer_noirq, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Promise 20230C and 20620 support -+ * -+ * This controller supports PIO0 to PIO2. We set PIO timings conservatively to -+ * allow for 50MHz Vesa Local Bus. The 20620 DMA support is weird being DMA to -+ * controller and PIO'd to the host and not supported. -+ */ -+ -+static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ int tries = 5; -+ int pio = adev->pio_mode - XFER_PIO_0; -+ u8 rt; -+ -+ do -+ { -+ inb(0x1F5); -+ outb(inb(0x1F2) | 0x80, 0x1F2); -+ inb(0x1F2); -+ inb(0x3F6); -+ inb(0x3F6); -+ inb(0x1F2); -+ inb(0x1F2); -+ } -+ while((inb(0x1F2) & 0x80) && --tries); -+ -+ outb(inb(0x1F4) & 0x07, 0x1F4); -+ -+ rt = inb(0x1F3); -+ rt &= 0x07 << (3 * adev->devno); -+ rt |= (3 * pio) << (3 * adev->devno); -+ -+ udelay(100); -+ outb(inb(0x1F2) | 0x01, 0x1F2); -+ udelay(100); -+ inb(0x1F5); -+ -+} -+ -+static void pdc_data_xfer_vlb(struct ata_port *ap, unsigned char *buf, unsigned int buflen, int write_data) -+{ -+ int slop = buflen & 3; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ -+ /* Perform the 32bit I/O synchronization sequence */ -+ inb(ap->ioaddr.nsect_addr); -+ inb(ap->ioaddr.nsect_addr); -+ inb(ap->ioaddr.nsect_addr); -+ -+ /* Now the data */ -+ -+ if (write_data) -+ outsl(ap->ioaddr.data_addr, buf, buflen >> 2); -+ else -+ insl(ap->ioaddr.data_addr, buf, buflen >> 2); -+ -+ if (unlikely(slop)) { -+ u32 pad; -+ if (write_data) { -+ memcpy(&pad, buf + buflen - slop, slop); -+ outl(le32_to_cpu(pad), ap->ioaddr.data_addr); -+ } else { -+ pad = cpu_to_le16(inl(ap->ioaddr.data_addr)); -+ memcpy(buf + buflen - slop, &pad, slop); -+ } -+ } -+ local_irq_restore(flags); -+} -+ -+static struct ata_port_operations pdc20230_port_ops = { -+ .set_piomode = pdc20230_set_piomode, -+ -+ .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, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = pdc_data_xfer_vlb, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Holtek 6560A support -+ * -+ * This controller supports PIO0 to PIO2 (no IORDY even though higher timings -+ * can be loaded). -+ */ -+ -+static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ u8 active, recover; -+ struct ata_timing t; -+ -+ /* Get the timing data in cycles. For now play safe at 50Mhz */ -+ ata_timing_compute(adev, adev->pio_mode, &t, 50000, 1000); -+ -+ active = FIT(t.active, 2, 15); -+ recover = FIT(t.recover, 4, 15); -+ -+ inb(0x3E6); -+ inb(0x3E6); -+ inb(0x3E6); -+ inb(0x3E6); -+ -+ outb(recover << 4 | active, ap->ioaddr.device_addr); -+ inb(ap->ioaddr.status_addr); -+} -+ -+static struct ata_port_operations ht6560a_port_ops = { -+ .set_piomode = ht6560a_set_piomode, -+ -+ .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, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, /* Check vlb/noirq */ -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Holtek 6560B support -+ * -+ * This controller supports PIO0 to PIO4. We honour the BIOS/jumper FIFO setting -+ * unless we see an ATAPI device in which case we force it off. -+ * -+ * FIXME: need to implement 2nd channel support. -+ */ -+ -+static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ u8 active, recover; -+ struct ata_timing t; -+ -+ /* Get the timing data in cycles. For now play safe at 50Mhz */ -+ ata_timing_compute(adev, adev->pio_mode, &t, 50000, 1000); -+ -+ active = FIT(t.active, 2, 15); -+ recover = FIT(t.recover, 2, 16); -+ recover &= 0x15; -+ -+ inb(0x3E6); -+ inb(0x3E6); -+ inb(0x3E6); -+ inb(0x3E6); -+ -+ outb(recover << 4 | active, ap->ioaddr.device_addr); -+ -+ if (adev->class != ATA_DEV_ATA) { -+ u8 rconf = inb(0x3E6); -+ if(rconf & 0x24) { -+ rconf &= ~ 0x24; -+ outb(rconf, 0x3E6); -+ } -+ } -+ inb(ap->ioaddr.status_addr); -+} -+ -+static struct ata_port_operations ht6560b_port_ops = { -+ .set_piomode = ht6560b_set_piomode, -+ -+ .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, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, /* FIXME: Check 32bit and noirq */ -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Opti 82C611A -+ * -+ * This controller supports PIO0 to PIO3. -+ */ -+ -+static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ u8 active, recover, setup; -+ struct ata_timing t; -+ struct ata_device *pair = &ap->device[adev->devno ^ 1]; -+ int clock; -+ int khz[4] = { 50000, 40000, 33000, 25000 }; -+ u8 rc; -+ -+ /* Enter configuration mode */ -+ inb(ap->ioaddr.error_addr); -+ inb(ap->ioaddr.error_addr); -+ -+ /* Read VLB clock strapping */ -+ clock = khz[inb(ap->ioaddr.lbah_addr) & 0x03]; -+ -+ /* Get the timing data in cycles */ -+ ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000); -+ -+ /* Setup timing is shared */ -+ if (ata_dev_present(pair)) { -+ struct ata_timing tp; -+ ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000); -+ -+ ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); -+ } -+ -+ active = FIT(t.active, 2, 17) - 2; -+ recover = FIT(t.recover, 1, 16) - 1; -+ setup = FIT(t.setup, 1, 4) - 1; -+ -+ /* Select the right timing bank for write timing */ -+ rc = inb(ap->ioaddr.lbal_addr); -+ rc &= 0x7F; -+ rc |= (adev->devno << 7); -+ outb(rc, ap->ioaddr.lbal_addr); -+ -+ /* Write the timings */ -+ outb(active << 4 | recover, ap->ioaddr.error_addr); -+ -+ /* Select the right bank for read timings, also -+ load the shared timings for address */ -+ rc = inb(ap->ioaddr.device_addr); -+ rc &= 0xC0; -+ rc |= adev->devno; /* Index select */ -+ rc |= (setup << 4) | 0x04; -+ outb(rc, ap->ioaddr.device_addr); -+ -+ /* Load the read timings */ -+ outb(active << 4 | recover, ap->ioaddr.data_addr); -+ -+ /* Ensure the timing register mode is right */ -+ rc = inb (ap->ioaddr.lbal_addr); -+ rc &= 0x73; -+ rc |= 0x84; -+ outb(rc, ap->ioaddr.lbal_addr); -+ -+ /* Exit command mode */ -+ outb(0x82, ap->ioaddr.nsect_addr); -+} -+ -+static struct ata_port_operations opti82c611a_port_ops = { -+ .set_piomode = opti82c611a_set_piomode, -+ -+ .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, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * legacy_init_one - attach a legacy interface -+ * @io: I/O port start -+ * @ctrl: control port -+ * @irq: interrupt line -+ * -+ * Register an ISA bus IDE interface. Such interfaces are PIO and we -+ * assume do not support IRQ sharing. -+ */ -+ -+static __init int legacy_init_one(unsigned long io, unsigned long ctrl, int irq) -+{ -+ struct ata_probe_ent ae; -+ int ret; -+ struct ata_port_operations *ops = &legacy_port_ops; -+ int pio_mask = 0x1F; -+ -+ if (request_region(io, 8, "pata_legacy") == NULL) -+ return -EBUSY; -+ if (request_region(ctrl, 1, "pata_legacy") == NULL) { -+ release_region(io, 8); -+ return -EBUSY; -+ } -+ -+ if (ht6560a == 1 && (io == 0x1F0 || io == 0x170)) { -+ ops = &ht6560a_port_ops; -+ pio_mask = 0x07; -+ } -+ if (ht6560b == 1 && (io == 0x1F0 || io == 0x170)) { -+ ops = &ht6560b_port_ops; -+ pio_mask = 0x1F; -+ } -+ if (opti82c611a == 1 && (io == 0x1F0 || io == 0x170)) { -+ ops = &opti82c611a_port_ops; -+ pio_mask = 0x0F; -+ } -+ else if (io == 0x1F0) { -+ /* Probes */ -+ inb(0x1F5); -+ outb(inb(0x1F2) | 0x80, 0x1F2); -+ inb(0x1F2); -+ inb(0x3F6); -+ inb(0x3F6); -+ inb(0x1F2); -+ inb(0x1F2); -+ -+ if ((inb(0x1F2) & 0x80) == 0) { -+ /* PDC20230 or 20630 ? */ -+ printk(KERN_INFO "PDC20230-C/20630 VLB ATA controller detected.\n"); -+ pio_mask = 0x07; -+ ops = &pdc20230_port_ops; -+ udelay(100); -+ inb(0x1F5); -+ } else { -+ outb(0x55, 0x1F2); -+ inb(0x1F2); -+ inb(0x1F2); -+ if(inb(0x1F2) == 0x00) { -+ printk(KERN_INFO "PDC20230-B VLB ATA controller detected.\n"); -+ } -+ } -+ } -+ memset(&ae, 0, sizeof(struct ata_probe_ent)); -+ INIT_LIST_HEAD(&ae.node); -+ ae.dev = NULL; -+ ae.port_ops = ops; -+ ae.sht = &legacy_sht; -+ ae.n_ports = 1; -+ ae.pio_mask = pio_mask; -+ ae.irq = irq; -+ ae.irq_flags = 0; -+ ae.host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_IRQ_MASK; -+ ae.port[0].cmd_addr = io; -+ ae.port[0].altstatus_addr = ctrl; -+ ae.port[0].ctl_addr = ctrl; -+ ata_std_ports(&ae.port[0]); -+ -+ ret = ata_device_add(&ae); -+ if (ret == 0) -+ return -ENODEV; -+ -+ legacy_host[nr_legacy_host++] = ae.host_set; -+ return 0; -+} -+ -+/** -+ * legacy_check_special_cases - ATA special cases -+ * @p: PCI device to check -+ * @master: set this if we find an ATA master -+ * @master: set this if we find an ATA secondary -+ * -+ * A small number of vendors implemented early PCI ATA interfaces on bridge logic -+ * without the ATA interface being PCI visible. Where we have a matching PCI driver -+ * we must skip the relevant device here. If we don't know about it then the legacy -+ * driver is the right driver anyway. -+ */ -+ -+static void legacy_check_special_cases(struct pci_dev *p, int *primary, int *secondary) -+{ -+ /* Cyrix CS5510 pre SFF MWDMA ATA on the bridge */ -+ if (p->vendor == 0x1078 && p->device == 0x0000) { -+ *primary = *secondary = 1; -+ return; -+ } -+ /* Cyrix CS5520 pre SFF MWDMA ATA on the bridge */ -+ if (p->vendor == 0x1078 && p->device == 0x0002) { -+ *primary = *secondary = 1; -+ return; -+ } -+ /* Intel MPIIX - PIO ATA on non PCI side of bridge */ -+ if (p->vendor == 0x8086 && p->device == 0x1234) { -+ u16 r; -+ pci_read_config_word(p, 0x6C, &r); -+ if (r & 0x8000) { /* ATA port enabled */ -+ if (r & 0x4000) -+ *secondary = 1; -+ else -+ *primary = 1; -+ } -+ return; -+ } -+} -+ -+/** -+ * legacy_init - attach legacy interfaces -+ * -+ * Attach legacy IDE interfaces by scanning the usual IRQ/port suspects. -+ * Right now we do not scan the ide0 and ide1 address but should do so -+ * for non PCI systems or systems with no PCI IDE legacy mode devices. -+ * If you fix that note there are special cases to consider like VLB -+ * drivers and CS5510/20. -+ */ -+ -+static __init int legacy_init(void) -+{ -+ int i; -+ int ct = 0; -+ int primary = 0; -+ int secondary = 0; -+ int last_port = NR_HOST; -+ -+ struct pci_dev *p = NULL; -+ -+ for_each_pci_dev(p) { -+ int r; -+ /* Check for any overlap of the system ATA mappings. Native mode controllers -+ stuck on these addresses or some devices in 'raid' mode won't be found by -+ the storage class test */ -+ for (r = 0; r < 6; r++) { -+ if (pci_resource_start(p, r) == 0x1f0) -+ primary = 1; -+ if (pci_resource_start(p, r) == 0x170) -+ secondary = 1; -+ } -+ /* Check for special cases */ -+ legacy_check_special_cases(p, &primary, &secondary); -+ -+ /* If PCI bus is present then don't probe for tertiary legacy ports */ -+ if (legacy_all == 0) -+ last_port = 2; -+ } -+ -+ -+ for (i = 0; i < last_port; i++) { -+ /* Skip primary if we have seen a PCI one */ -+ if (i == 0 && primary == 1) -+ continue; -+ /* Skip secondary if we have seen a PCI one */ -+ if (i == 1 && secondary == 1) -+ continue; -+ if (legacy_init_one(legacy_port[i], -+ legacy_port[i] + 0x0206, -+ legacy_irq[i]) == 0) -+ ct++; -+ } -+ if (ct != 0) -+ return 0; -+ return -ENODEV; -+} -+ -+static __exit void legacy_exit(void) -+{ -+ int i; -+ -+ for (i = 0; i < nr_legacy_host; i++) { -+ struct ata_port *ap =legacy_host[i]->ports[0]; -+ unsigned long io = ap->ioaddr.cmd_addr; -+ unsigned long ctrl = ap->ioaddr.ctl_addr; -+ ata_host_set_remove(legacy_host[i]); -+ release_region(io, 8); -+ release_region(ctrl, 1); -+ } -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for legacy ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); -+ -+/** -+ * legacy_probe_all - setup argument handler -+ * @unused: unused -+ * -+ * Called when the probe_all argument is passed to this driver. This indicates -+ * that we should check all the legacy ATA addresses even if PCI is present. Should -+ * only ever be needed on very strange PCI/legacy combinations -+ */ -+ -+static int __init legacy_probe_all(char *unused) -+{ -+ legacy_all = 1; -+ return 1; -+} -+ -+__setup("probe-all", legacy_probe_all); -+ -+/** -+ * legacy_ht6560a - setup argument handler -+ * @unused: unused -+ * -+ * Called when the ht6560a argument is passed to this driver. This indicates -+ * that we should check all the legacy ATA addresses even if PCI is present. Should -+ * only ever be needed on very strange PCI/legacy combinations -+ */ -+ -+static int __init legacy_ht6560a(char *unused) -+{ -+ ht6560a = 1; -+ return 1; -+} -+ -+__setup("ht6560a", legacy_ht6560a); -+ -+/** -+ * legacy_ht6560b - setup argument handler -+ * @unused: unused -+ * -+ * Called when the ht6560b argument is passed to this driver. This indicates -+ * that we should check all the legacy ATA addresses even if PCI is present. Should -+ * only ever be needed on very strange PCI/legacy combinations -+ */ -+ -+static int __init legacy_ht6560b(char *unused) -+{ -+ ht6560b = 1; -+ return 1; -+} -+ -+__setup("ht6560b", legacy_ht6560b); -+ -+/** -+ * legacy_ht6560a - setup argument handler -+ * @unused: unused -+ * -+ * Called when the ht6560a argument is passed to this driver. This indicates -+ * that we should check all the legacy ATA addresses even if PCI is present. Should -+ * only ever be needed on very strange PCI/legacy combinations -+ */ -+ -+static int __init legacy_opti82c611a(char *unused) -+{ -+ opti82c611a = 1; -+ return 1; -+} -+ -+__setup("opti82c611a", legacy_opti82c611a); -+ -+module_init(legacy_init); -+module_exit(legacy_exit); -+ -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_mpiix.c linux-2.6.16-rc2/drivers/scsi/pata_mpiix.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_mpiix.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_mpiix.c 2006-01-21 16:55:12.000000000 +0000 -@@ -0,0 +1,303 @@ -+/* -+ * pata_mpiix.c - Intel MPIIX PATA for new ATA layer -+ * (C) 2005-2006 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * The MPIIX is different enough to the PIIX4 and friends that we give it -+ * a separate driver. The old ide/pci code handles this by just not tuning -+ * MPIIX at all. -+ * -+ * The MPIIX also differs in another important way from the majority of PIIX -+ * devices. The chip is a bridge (pardon the pun) between the old world of -+ * ISA IDE and PCI IDE. Although the ATA timings are PCI configured the actual -+ * IDE controller is not decoded in PCI space and the chip does not claim to -+ * be IDE class PCI. This requires slightly non-standard probe logic compared -+ * with PCI IDE and also that we do not disable the device when our driver is -+ * unloaded (as it has many other functions). -+ * -+ * The driver conciously keeps this logic internally to avoid pushing quirky -+ * PATA history into the clean libata layer. -+ * -+ * Thinkpad specific note: If you boot an MPIIX using thinkpad with a PCMCIA -+ * hard disk present this driver will not detect it. This is not a bug. In this -+ * configuration the secondary port of the MPIIX is disabled and the addresses -+ * are decoded by the PCMCIA bridge and therefore are for a generic IDE driver -+ * to operate. -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_mpiix" -+#define DRV_VERSION "0.4" -+ -+/** -+ * mpiix_phy_reset - probe reset -+ * @ap: ATA port -+ * -+ * Perform the ATA probe and bus reset sequence plus specific handling -+ * for this hardware. The MPIIX has the enable bits in a different place -+ * to PIIX4 and friends. As a pure PIO device it has no cable detect -+ */ -+ -+static void mpiix_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static const struct pci_bits mpiix_enable_bits[] = { -+ { 0x6D, 1, 0x80, 0x80 }, -+ { 0x6F, 1, 0x80, 0x80 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &mpiix_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * mpiix_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. The MPIIX allows us to program the -+ * IORDY sample point (2-5 clocks), recovery 1-4 clocks and whether -+ * prefetching or iordy are used. -+ * -+ * This would get very ugly because we can only program timing for one -+ * device at a time, the other gets PIO0. Fortunately libata calls -+ * our qc_issue_prot command before a command is issued so we can -+ * flip the timings back and forth to reduce the pain. -+ */ -+ -+static void mpiix_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ int control = 0; -+ int pio = adev->pio_mode - XFER_PIO_0; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u16 idetim; -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; -+ -+ pci_read_config_word(pdev, 0x6C, &idetim); -+ /* Mask the IORDY/TIME/PPE0 bank for this device */ -+ if (adev->class == ATA_DEV_ATA) -+ control |= 4; /* PPE enable for disk */ -+ if (ata_pio_need_iordy(adev)) -+ control |= 2; /* IORDY */ -+ if (pio > 0) -+ control |= 1; /* This drive is on the fast timing bank */ -+ -+ /* Mask out timing and clear both TIME bank selects */ -+ idetim &= 0xCCEE; -+ idetim &= ~(0x07 << (2 * adev->devno)); -+ idetim |= (control << (2 * adev->devno)); -+ -+ idetim |= (timings[pio][0] << 12) | (timings[pio][1] << 8); -+ pci_write_config_word(pdev, 0x6C, idetim); -+ -+ /* We use ap->private_data as a pointer to the device currently -+ loaded for timing */ -+ ap->private_data = adev; -+} -+ -+/** -+ * mpiix_qc_issue_prot - command issue -+ * @qc: command pending -+ * -+ * Called when the libata layer is about to issue a command. We wrap -+ * this interface so that we can load the correct ATA timings if -+ * neccessary. Our logic also clears TIME0/TIME1 for the other device so -+ * that, even if we get this wrong, cycles to the other device will -+ * be made PIO0. -+ */ -+ -+static int mpiix_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ -+ /* If modes have been configured and the channel data is not loaded -+ then load it. We have to check if pio_mode is set as the core code -+ does not set adev->pio_mode to XFER_PIO_0 while probing as would be -+ logical */ -+ -+ if (adev->pio_mode && adev != ap->private_data) -+ mpiix_set_piomode(ap, adev); -+ -+ return ata_qc_issue_prot(qc); -+} -+ -+static struct scsi_host_template mpiix_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations mpiix_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = mpiix_set_piomode, -+ -+ .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 = mpiix_phy_reset, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = mpiix_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ /* Single threaded by the PCI probe logic */ -+ static struct ata_probe_ent probe[2]; -+ static int printed_version; -+ u16 idetim; -+ int enabled; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); -+ -+ /* MPIIX has many functions which can be turned on or off according -+ to other devices present. Make sure IDE is enabled before we try -+ and use it */ -+ -+ pci_read_config_word(dev, 0x6C, &idetim); -+ if (!(idetim & 0x8000)) -+ return -ENODEV; -+ -+ /* We do our own plumbing to avoid leaking special cases for whacko -+ ancient hardware into the core code. There are two issues to -+ worry about. #1 The chip is a bridge so if in legacy mode and -+ without BARs set fools the setup. #2 If you pci_disable_device -+ the MPIIX your box goes castors up */ -+ -+ INIT_LIST_HEAD(&probe[0].node); -+ probe[0].dev = pci_dev_to_dev(dev); -+ probe[0].port_ops = &mpiix_port_ops; -+ probe[0].sht = &mpiix_sht; -+ probe[0].pio_mask = 0x1F; -+ probe[0].irq = 14; -+ probe[0].irq_flags = SA_SHIRQ; -+ probe[0].host_flags = ATA_FLAG_SLAVE_POSS; -+ probe[0].legacy_mode = 1; -+ probe[0].hard_port_no = 0; -+ probe[0].n_ports = 1; -+ probe[0].port[0].cmd_addr = 0x1F0; -+ probe[0].port[0].ctl_addr = 0x3F6; -+ probe[0].port[0].altstatus_addr = 0x3F6; -+ -+ /* The secondary lurks at different addresses but is otherwise -+ the same beastie */ -+ -+ INIT_LIST_HEAD(&probe[1].node); -+ probe[1] = probe[0]; -+ probe[1].irq = 15; -+ probe[1].hard_port_no = 1; -+ probe[1].port[0].cmd_addr = 0x170; -+ probe[1].port[0].ctl_addr = 0x376; -+ probe[1].port[0].altstatus_addr = 0x376; -+ -+ /* Let libata fill in the port details */ -+ ata_std_ports(&probe[0].port[0]); -+ ata_std_ports(&probe[1].port[0]); -+ -+ /* Now add the port that is active */ -+ enabled = (idetim & 0x4000) ? 1 : 0; -+ -+ if(ata_device_add(&probe[enabled])) -+ return 0; -+ return -ENODEV; -+} -+ -+/** -+ * mpiix_remove_one - device unload -+ * @pdev: PCI device being removed -+ * -+ * Handle an unplug/unload event for a PCI device. Unload the -+ * PCI driver but do not use the default handler as we *MUST NOT* -+ * disable the device as it has other functions. -+ */ -+ -+static void __devexit mpiix_remove_one(struct pci_dev *pdev) -+{ -+ struct device *dev = pci_dev_to_dev(pdev); -+ struct ata_host_set *host_set = dev_get_drvdata(dev); -+ -+ ata_host_set_remove(host_set); -+ dev_set_drvdata(dev, NULL); -+} -+ -+ -+ -+static const struct pci_device_id mpiix[] = { -+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, -+ { 0, }, -+}; -+ -+static struct pci_driver mpiix_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = mpiix, -+ .probe = mpiix_init_one, -+ .remove = mpiix_remove_one -+}; -+ -+static int __init mpiix_init(void) -+{ -+ return pci_register_driver(&mpiix_pci_driver); -+} -+ -+ -+static void __exit mpiix_exit(void) -+{ -+ pci_unregister_driver(&mpiix_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Intel MPIIX"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, mpiix); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(mpiix_init); -+module_exit(mpiix_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_netcell.c linux-2.6.16-rc2/drivers/scsi/pata_netcell.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_netcell.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_netcell.c 2006-02-07 13:48:27.721485832 +0000 -@@ -0,0 +1,178 @@ -+/* -+ * pata_netcell.c - Netcell PATA driver -+ * -+ * (c) 2006 Red Hat <alan@redhat.com> -+ */ -+ -+#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/device.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/ata.h> -+ -+#define DRV_NAME "pata_netcell" -+#define DRV_VERSION "0.1" -+ -+/** -+ * netcell_cable_detect - check for 40/80 pin -+ * @ap: Port -+ * -+ * Cables are handled by the RAID controller. Report 80 pin. -+ */ -+ -+static int netcell_cable_detect(struct ata_port *ap) -+{ -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * netcell_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void netcell_phy_reset(struct ata_port *ap) -+{ -+ /* If you have enable bits for devices ... , if not delete */ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ ap->cbl = netcell_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/* No PIO or DMA methods needed for this device */ -+ -+static struct scsi_host_template netcell_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, -+ /* Special handling needed if you have sector or LBA48 limits */ -+ .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, -+ /* Use standard CHS mapping rules */ -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static const struct ata_port_operations netcell_ops = { -+ .port_disable = ata_port_disable, -+ -+ /* Task file is PCI ATA format, use helpers */ -+ .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 = netcell_phy_reset, -+ -+ /* BMDMA handling is PCI ATA format, use helpers */ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, /* In -ac only right now */ -+ -+ /* Timeout handling. Special recovery hooks here */ -+ .eng_timeout = ata_eng_timeout, -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ /* Generic PATA PCI ATA helpers */ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+ -+/** -+ * netcell_init_one - Register Netcell ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in netcell_pci_tbl matching with @pdev -+ * -+ * Called from kernel PCI layer. -+ * -+ * LOCKING: -+ * Inherited from PCI layer (may sleep). -+ * -+ * RETURNS: -+ * Zero on success, or -ERRNO value. -+ */ -+ -+static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ static struct ata_port_info info = { -+ .sht = &netcell_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ /* Actually we don't really care about these as the -+ firmware deals with it */ -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = 0x3f, /* UDMA 133 */ -+ .port_ops = &netcell_ops, -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, -+ "version " DRV_VERSION "\n"); -+ -+ /* Any chip specific setup/optimisation/messages here */ -+ ata_pci_clear_simplex(pdev); -+ -+ /* And let the library code do the work */ -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id netcell_pci_tbl[] = { -+ { 0x169C, 0x0044, PCI_ANY_ID, PCI_ANY_ID, }, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver netcell_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = netcell_pci_tbl, -+ .probe = netcell_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init netcell_init(void) -+{ -+ return pci_register_driver(&netcell_pci_driver); -+} -+ -+static void __exit netcell_exit(void) -+{ -+ pci_unregister_driver(&netcell_pci_driver); -+} -+ -+ -+module_init(netcell_init); -+module_exit(netcell_exit); -+ -+MODULE_AUTHOR(""); -+MODULE_DESCRIPTION("SCSI low-level driver for Netcell PATA RAID"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, netcell_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_oldpiix.c linux-2.6.16-rc2/drivers/scsi/pata_oldpiix.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_oldpiix.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_oldpiix.c 2006-01-21 16:55:29.000000000 +0000 -@@ -0,0 +1,327 @@ -+/* -+ * pata_oldpiix.c - Intel PATA/SATA controllers -+ * -+ * (C) 2005 Red Hat <alan@redhat.com> -+ * -+ * Some parts based on ata_piix.c by Jeff Garzik and others. -+ * -+ * Early PIIX differs significantly from the later PIIX as it lacks -+ * SITRE and the slave timing registers. This means that you have to -+ * set timing per channel, or be clever. Libata tells us whenever it -+ * does drive selection and we use this to reload the timings. -+ * -+ * Because of these behaviour differences PIIX gets its own driver module. -+ */ -+ -+#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/device.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/ata.h> -+ -+#define DRV_NAME "pata_oldpiix" -+#define DRV_VERSION "0.3" -+ -+/** -+ * oldpiix_pata_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void oldpiix_pata_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static const struct pci_bits oldpiix_enable_bits[] = { -+ { 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */ -+ { 0x43U, 1U, 0x80UL, 0x80UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * oldpiix_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: um -+ * -+ * Set PIO mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void oldpiix_set_piomode (struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int pio = adev->pio_mode - XFER_PIO_0; -+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -+ unsigned int idetm_port= ap->hard_port_no ? 0x42 : 0x40; -+ u16 idetm_data; -+ int control = 0; -+ -+ /* -+ * See Intel Document 298600-004 for the timing programing rules -+ * for PIIX/ICH. Note that the early PIIX does not have the slave -+ * timing port at 0x44. -+ */ -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; -+ -+ if (pio > 2) -+ control |= 1; /* TIME1 enable */ -+ if (ata_pio_need_iordy(adev)) -+ control |= 2; /* IE IORDY */ -+ -+ /* Intel specifies that the PPE functionality is for disk only */ -+ if (adev->class == ATA_DEV_ATA) -+ control |= 4; /* PPE enable */ -+ -+ pci_read_config_word(dev, idetm_port, &idetm_data); -+ -+ /* Enable PPE, IE and TIME as appropriate. Clear the other -+ drive timing bits */ -+ if (adev->devno == 0) { -+ idetm_data &= 0xCCE0; -+ idetm_data |= control; -+ } else { -+ idetm_data &= 0xCC0E; -+ idetm_data |= (control << 4); -+ } -+ idetm_data |= (timings[pio][0] << 12) | -+ (timings[pio][1] << 8); -+ pci_write_config_word(dev, idetm_port, idetm_data); -+ -+ /* Track which port is configured */ -+ ap->private_data = adev; -+} -+ -+/** -+ * oldpiix_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * @isich: True if the device is an ICH and has IOCFG registers -+ * -+ * Set MWDMA mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void oldpiix_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -+ u8 idetm_port = ap->hard_port_no ? 0x42 : 0x40; -+ u16 idetm_data; -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; -+ -+ /* -+ * MWDMA is driven by the PIO timings. We must also enable -+ * IORDY unconditionally along with TIME1. PPE has already -+ * been set when the PIO timing was set. -+ */ -+ -+ unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0; -+ unsigned int control; -+ const unsigned int needed_pio[3] = { -+ XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 -+ }; -+ int pio = needed_pio[mwdma] - XFER_PIO_0; -+ -+ pci_read_config_word(dev, idetm_port, &idetm_data); -+ -+ control = 3; /* IORDY|TIME0 */ -+ /* Intel specifies that the PPE functionality is for disk only */ -+ if (adev->class == ATA_DEV_ATA) -+ control |= 4; /* PPE enable */ -+ -+ /* If the drive MWDMA is faster than it can do PIO then -+ we must force PIO into PIO0 */ -+ -+ if (adev->pio_mode < needed_pio[mwdma]) -+ /* Enable DMA timing only */ -+ control |= 8; /* PIO cycles in PIO0 */ -+ -+ /* Mask out the relevant control and timing bits we will load. Also -+ clear the other drive TIME register as a precaution */ -+ if (adev->devno == 0) { -+ idetm_data &= 0xCCE0; -+ idetm_data |= control; -+ } else { -+ idetm_data &= 0xCC0E; -+ idetm_data |= (control << 4); -+ } -+ idetm_data |= (timings[pio][0] << 12) | (timings[pio][1] << 8); -+ pci_write_config_word(dev, idetm_port, idetm_data); -+ -+ /* Track which port is configured */ -+ ap->private_data = adev; -+} -+ -+/** -+ * oldpiix_qc_issue_prot - command issue -+ * @qc: command pending -+ * -+ * Called when the libata layer is about to issue a command. We wrap -+ * this interface so that we can load the correct ATA timings if -+ * neccessary. Our logic also clears TIME0/TIME1 for the other device so -+ * that, even if we get this wrong, cycles to the other device will -+ * be made PIO0. -+ */ -+ -+static int oldpiix_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ -+ if (adev != ap->private_data) { -+ if (adev->dma_mode) -+ oldpiix_set_dmamode(ap, adev); -+ else if (adev->pio_mode) -+ oldpiix_set_piomode(ap, adev); -+ } -+ return ata_qc_issue_prot(qc); -+} -+ -+ -+static struct scsi_host_template oldpiix_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, -+// .ordered_flush = 1, -+}; -+ -+static const struct ata_port_operations oldpiix_pata_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = oldpiix_set_piomode, -+ .set_dmamode = oldpiix_set_dmamode, -+ -+ .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 = oldpiix_pata_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = oldpiix_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+ -+/** -+ * oldpiix_init_one - Register PIIX ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in oldpiix_pci_tbl matching with @pdev -+ * -+ * Called from kernel PCI layer. We probe for combined mode (sigh), -+ * and then hand over control to libata, for it to do the rest. -+ * -+ * LOCKING: -+ * Inherited from PCI layer (may sleep). -+ * -+ * RETURNS: -+ * Zero on success, or -ERRNO value. -+ */ -+ -+static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ static struct ata_port_info info = { -+ .sht = &oldpiix_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma1-2 */ -+ .port_ops = &oldpiix_pata_ops, -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, -+ "version " DRV_VERSION "\n"); -+ -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id oldpiix_pci_tbl[] = { -+ { 0x8086, 0x1230, PCI_ANY_ID, PCI_ANY_ID, }, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver oldpiix_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = oldpiix_pci_tbl, -+ .probe = oldpiix_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init oldpiix_init(void) -+{ -+ return pci_register_driver(&oldpiix_pci_driver); -+} -+ -+static void __exit oldpiix_exit(void) -+{ -+ pci_unregister_driver(&oldpiix_pci_driver); -+} -+ -+ -+module_init(oldpiix_init); -+module_exit(oldpiix_exit); -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("SCSI low-level driver for early PIIX series controllers"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, oldpiix_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_opti.c linux-2.6.16-rc2/drivers/scsi/pata_opti.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_opti.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_opti.c 2006-01-21 16:55:42.000000000 +0000 -@@ -0,0 +1,268 @@ -+/* -+ * pata_opti.c - ATI PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based on -+ * linux/drivers/ide/pci/opti621.c Version 0.7 Sept 10, 2002 -+ * -+ * Copyright (C) 1996-1998 Linus Torvalds & authors (see below) -+ * -+ * Authors: -+ * Jaromir Koutek <miri@punknet.cz>, -+ * Jan Harkes <jaharkes@cwi.nl>, -+ * Mark Lord <mlord@pobox.com> -+ * Some parts of code are from ali14xx.c and from rz1000.c. -+ * -+ * Also consulted the FreeBSD prototype driver by Kevin Day to try -+ * and resolve some confusions. -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_opti" -+#define DRV_VERSION "0.1.1" -+ -+enum { -+ READ_REG = 0, /* index of Read cycle timing register */ -+ WRITE_REG = 1, /* index of Write cycle timing register */ -+ CNTRL_REG = 3, /* index of Control register */ -+ STRAP_REG = 5, /* index of Strap register */ -+ MISC_REG = 6 /* index of Miscellaneous register */ -+}; -+ -+/** -+ * opti_phy_reset - probe reset -+ * @ap: ATA port -+ * -+ * Perform the ATA probe and bus reset sequence plus specific handling -+ * for this hardware. The Opti needs little handling - we have no UDMA66 -+ * capability that needs cable detection. All we must do is check the port -+ * is enabled. -+ */ -+ -+static void opti_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static const struct pci_bits opti_enable_bits[] = { -+ { 0x45, 1, 0x80, 0x00 }, -+ { 0x45, 1, 0x08, 0x00 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * opti_write_reg - control register setup -+ * @ap: ATA port -+ * @value: value -+ * @reg: control register number -+ * -+ * The Opti uses magic 'trapdoor' register accesses to do configuration -+ * rather than using PCI space as other controllers do. The double inw -+ * on the error register activates configuration mode. We can then write -+ * the control register -+ */ -+ -+static void opti_write_reg(struct ata_port *ap, u8 val, int reg) -+{ -+ unsigned long regio = ap->ioaddr.cmd_addr; -+ inw(regio + 1); -+ inw(regio + 1); -+ outb(3, regio + 2); -+ outb(val, regio + reg); -+ outb(0x83, regio + 2); -+} -+ -+#if 0 -+/** -+ * opti_read_reg - control register read -+ * @ap: ATA port -+ * @reg: control register number -+ * -+ * The Opti uses magic 'trapdoor' register accesses to do configuration -+ * rather than using PCI space as other controllers do. The double inw -+ * on the error register activates configuration mode. We can then read -+ * the control register -+ */ -+ -+static u8 opti_read_reg(struct ata_port *ap, int reg) -+{ -+ unsigned long regio = ap->ioaddr.cmd_addr; -+ u8 ret; -+ inw(regio + 1); -+ inw(regio + 1); -+ outb(3, regio + 2); -+ ret = inb(regio + reg); -+ outb(0x83, regio + 2); -+} -+#endif -+ -+/** -+ * opti_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. Timing numbers are taken from -+ * the FreeBSD driver then pre computed to keep the code clean. There -+ * are two tables depending on the hardware clock speed. -+ */ -+ -+static void opti_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct ata_device *pair = &ap->device[1 - adev->devno]; -+ int clock; -+ int pio = adev->pio_mode - XFER_PIO_0; -+ unsigned long regio = ap->ioaddr.cmd_addr; -+ u8 addr; -+ -+ /* Address table precomputed with prefetch off and a DCLK of 2 */ -+ static const u8 addr_timing[2][5] = { -+ { 0x30, 0x20, 0x20, 0x10, 0x10 }, -+ { 0x20, 0x20, 0x10, 0x10, 0x10 } -+ }; -+ static const u8 data_rec_timing[2][5] = { -+ { 0x6B, 0x56, 0x42, 0x32, 0x31 }, -+ { 0x58, 0x44, 0x32, 0x22, 0x21 } -+ }; -+ -+ outb(0xff, regio + 5); -+ clock = inw(regio + 5) & 1; -+ -+ /* -+ * As with many controllers the address setup time is shared -+ * and must suit both devices if present. -+ */ -+ -+ addr = addr_timing[clock][pio]; -+ if (ata_dev_present(pair)) { -+ /* Hardware constraint */ -+ u8 pair_addr = addr_timing[clock][pair->pio_mode - XFER_PIO_0]; -+ if(pair_addr > addr) -+ addr = pair_addr; -+ } -+ -+ /* Commence primary programming sequence */ -+ opti_write_reg(ap, adev->devno, MISC_REG); -+ opti_write_reg(ap, data_rec_timing[clock][pio], READ_REG); -+ opti_write_reg(ap, data_rec_timing[clock][pio], WRITE_REG); -+ opti_write_reg(ap, addr, MISC_REG); -+ -+ /* Programming sequence complete, override strapping */ -+ opti_write_reg(ap, 0x85, CNTRL_REG); -+} -+ -+static struct scsi_host_template opti_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations opti_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = opti_set_piomode, -+/* .set_dmamode = opti_set_dmamode, */ -+ .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 = opti_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &opti_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .port_ops = &opti_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ static int printed_version; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); -+ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static const struct pci_device_id opti[] = { -+ { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { 0, }, -+}; -+ -+static struct pci_driver opti_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = opti, -+ .probe = opti_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init opti_init(void) -+{ -+ return pci_register_driver(&opti_pci_driver); -+} -+ -+ -+static void __exit opti_exit(void) -+{ -+ pci_unregister_driver(&opti_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Opti 621/621X"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, opti); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(opti_init); -+module_exit(opti_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_pcmcia.c linux-2.6.16-rc2/drivers/scsi/pata_pcmcia.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_pcmcia.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_pcmcia.c 2006-01-21 16:55:56.000000000 +0000 -@@ -0,0 +1,406 @@ -+/* -+ * pata-pcmcia.c - PCMCIA PATA controller driver. -+ * Copyright 2005/2006 Red Hat Inc <alan@redhat.com>, all rights reserved. -+ * -+ * Heavily based upon ide-cs.c -+ * The initial developer of the original code is David A. Hinds -+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds -+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/ata.h> -+#include <linux/libata.h> -+ -+#include <pcmcia/cs_types.h> -+#include <pcmcia/cs.h> -+#include <pcmcia/cistpl.h> -+#include <pcmcia/ds.h> -+#include <pcmcia/cisreg.h> -+#include <pcmcia/ciscode.h> -+ -+ -+#define DRV_NAME "pata_pcmcia" -+#define DRV_VERSION "0.1" -+ -+/* -+ * Private data structure to glue stuff together -+ */ -+ -+struct ata_pcmcia_info { -+ dev_link_t link; -+ int ndev; -+ dev_node_t node; -+}; -+ -+static struct scsi_host_template pcmcia_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations pcmcia_port_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, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+#define CS_CHECK(fn, ret) \ -+do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -+ -+/** -+ * pcmcia_init_one - attach an pcmcia interface -+ * @pdev: pcmcia device -+ * -+ * Register a PCMCIA IDE interface. Such interfaces are PIO 0 and -+ * non shared IRQ. -+ */ -+ -+static int pcmcia_init_one(struct pcmcia_device *pdev) -+{ -+ struct ata_probe_ent ae; -+ dev_link_t *link; -+ struct ata_pcmcia_info *info; -+ client_handle_t handle; -+ tuple_t tuple; -+ struct { -+ unsigned short buf[128]; -+ cisparse_t parse; -+ config_info_t conf; -+ cistpl_cftable_entry_t dflt; -+ } *stk = NULL; -+ cistpl_cftable_entry_t *cfg; -+ int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM; -+ unsigned long io_base, ctl_base; -+ -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (info == NULL) -+ return -ENOMEM; -+ -+ link = &info->link; -+ link->priv = info; -+ -+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; -+ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; -+ link->io.IOAddrLines = 3; -+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; -+ link->irq.IRQInfo1 = IRQ_LEVEL_ID; -+ link->conf.Attributes = CONF_ENABLE_IRQ; -+ link->conf.Vcc = 50; -+ link->conf.IntType = INT_MEMORY_AND_IO; -+ -+ link->handle = pdev; -+ pdev->instance = link; -+ -+ handle = link->handle; -+ -+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -+ -+ stk = kzalloc(sizeof(*stk), GFP_KERNEL); -+ if (!stk) -+ goto out1; -+ -+ cfg = &stk->parse.cftable_entry; -+ -+ tuple.TupleData = (cisdata_t *)&stk->buf; -+ tuple.TupleOffset = 0; -+ tuple.TupleDataMax = 255; -+ tuple.Attributes = 0; -+ tuple.DesiredTuple = CISTPL_CONFIG; -+ -+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); -+ CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); -+ CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &stk->parse)); -+ link->conf.ConfigBase = stk->parse.config.base; -+ link->conf.Present = stk->parse.config.rmask[0]; -+ -+ tuple.DesiredTuple = CISTPL_MANFID; -+ if (!pcmcia_get_first_tuple(handle, &tuple) && !pcmcia_get_tuple_data(handle, &tuple) && !pcmcia_parse_tuple(handle, &tuple, &stk->parse)) -+ is_kme = ((stk->parse.manfid.manf == MANFID_KME) && ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) || (stk->parse.manfid.card == PRODID_KME_KXLC005_B))); -+ -+ /* Configure card */ -+ link->state |= DEV_CONFIG; -+ -+ /* Not sure if this is right... look up the current Vcc */ -+ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &stk->conf)); -+ link->conf.Vcc = stk->conf.Vcc; -+ -+ pass = io_base = ctl_base = 0; -+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; -+ tuple.Attributes = 0; -+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); -+ -+ while (1) { -+ if (pcmcia_get_tuple_data(handle, &tuple) != 0) -+ goto next_entry; -+ if (pcmcia_parse_tuple(handle, &tuple, &stk->parse) != 0) -+ goto next_entry; -+ /* Check for matching Vcc, unless we're desperate */ -+ if (!pass) { -+ if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { -+ if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) -+ goto next_entry; -+ } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { -+ if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) -+ goto next_entry; -+ } -+ } -+ -+ if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) -+ link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; -+ else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) -+ link->conf.Vpp1 = link->conf.Vpp2 = stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; -+ -+ if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) { -+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io; -+ link->conf.ConfigIndex = cfg->index; -+ link->io.BasePort1 = io->win[0].base; -+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; -+ if (!(io->flags & CISTPL_IO_16BIT)) -+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; -+ if (io->nwin == 2) { -+ link->io.NumPorts1 = 8; -+ link->io.BasePort2 = io->win[1].base; -+ link->io.NumPorts2 = (is_kme) ? 2 : 1; -+ if (pcmcia_request_io(link->handle, &link->io) != 0) -+ goto next_entry; -+ io_base = link->io.BasePort1; -+ ctl_base = link->io.BasePort2; -+ } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { -+ link->io.NumPorts1 = io->win[0].len; -+ link->io.NumPorts2 = 0; -+ if (pcmcia_request_io(link->handle, &link->io) != 0) -+ goto next_entry; -+ io_base = link->io.BasePort1; -+ ctl_base = link->io.BasePort1 + 0x0e; -+ } else goto next_entry; -+ /* If we've got this far, we're done */ -+ break; -+ } -+next_entry: -+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT) -+ memcpy(&stk->dflt, cfg, sizeof(stk->dflt)); -+ if (pass) { -+ CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); -+ } else if (pcmcia_get_next_tuple(handle, &tuple) != 0) { -+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); -+ memset(&stk->dflt, 0, sizeof(stk->dflt)); -+ pass++; -+ } -+ } -+ -+ if (is_kme) -+ outb(0x81, ctl_base + 0x01); -+ -+ /* FIXME: Could be more ports at base + 0x10 but we only deal with -+ one right now */ -+ -+ if (link->io.NumPorts1 >= 0x20) -+ printk(KERN_WARNING DRV_NAME ": second channel not yet supported.\n"); -+ -+ /* -+ * Having done the PCMCIA plumbing the ATA side is relatively -+ * sane. -+ */ -+ -+ memset(&ae, 0, sizeof(struct ata_probe_ent)); -+ INIT_LIST_HEAD(&ae.node); -+ ae.dev = &pdev->dev; -+ ae.port_ops = &pcmcia_port_ops; -+ ae.sht = &pcmcia_sht; -+ ae.n_ports = 1; -+ ae.pio_mask = 1; /* ISA so PIO 0 cycles */ -+ ae.irq = link->irq.AssignedIRQ; -+ ae.irq_flags = 0; -+ ae.host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_IRQ_MASK; -+ ae.port[0].cmd_addr = io_base; -+ ae.port[0].altstatus_addr = ctl_base; -+ ae.port[0].ctl_addr = ctl_base; -+ ata_std_ports(&ae.port[0]); -+ -+ if (ata_device_add(&ae) == 0) -+ goto failed; -+ -+ info->ndev = 1; -+ link->dev = &info->node; -+ link->state &= ~DEV_CONFIG_PENDING; -+ kfree(stk); -+ return 0; -+ -+cs_failed: -+ cs_error(link->handle, last_fn, last_ret); -+failed: -+ kfree(stk); -+ info->ndev = 0; -+ link->dev = NULL; -+ -+ pcmcia_release_configuration(link->handle); -+ pcmcia_release_io(link->handle, &link->io); -+ pcmcia_release_irq(link->handle, &link->irq); -+ -+ link->state &= ~DEV_CONFIG; -+out1: -+ kfree(info); -+ return ret; -+} -+ -+/** -+ * pcmcia_remove_one - unplug an pcmcia interface -+ * @pdev: pcmcia device -+ * -+ * A PCMCIA ATA device has been unplugged. Perform the needed -+ * cleanup. Also called on module unload for any active devices. -+ */ -+ -+void pcmcia_remove_one(struct pcmcia_device *pdev) -+{ -+ dev_link_t *link = dev_to_instance(pdev); -+ struct ata_pcmcia_info *info = link->priv; -+ struct device *dev = &pdev->dev; -+ -+ if (link->state & DEV_CONFIG) { -+ if (info->ndev) { -+ struct ata_host_set *host_set = dev_get_drvdata(dev); -+ ata_host_set_remove(host_set); -+ dev_set_drvdata(dev, NULL); -+ } -+ info->ndev = 0; -+ link->dev = NULL; -+ -+ pcmcia_release_configuration(link->handle); -+ pcmcia_release_io(link->handle, &link->io); -+ pcmcia_release_irq(link->handle, &link->irq); -+ link->state &= ~DEV_CONFIG; -+ } -+ kfree(link->priv); -+} -+ -+static int pcmcia_suspend(struct pcmcia_device *dev) -+{ -+ dev_link_t *link = dev_to_instance(dev); -+ -+ link->state |= DEV_SUSPEND; -+ if (link->state & DEV_CONFIG) -+ pcmcia_release_configuration(link->handle); -+ -+ return 0; -+} -+ -+static int pcmcia_resume(struct pcmcia_device *dev) -+{ -+ dev_link_t *link = dev_to_instance(dev); -+ -+ link->state &= ~DEV_SUSPEND; -+ if (DEV_OK(link)) -+ pcmcia_request_configuration(link->handle, &link->conf); -+ -+ return 0; -+} -+ -+static struct pcmcia_device_id pcmcia_devices[] = { -+ PCMCIA_DEVICE_FUNC_ID(4), -+ PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */ -+ PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), -+ PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), -+ PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ -+ PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), -+ PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ -+ PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */ -+ PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001), -+ PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */ -+ PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0), -+ PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74), -+ PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9), -+ PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591), -+ PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728), -+ PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591), -+ PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4), -+ PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde), -+ PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf), -+ PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), -+ PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), -+ PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), -+ PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae), -+ PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178), -+ PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753), -+ PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b), -+ PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), -+ PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674), -+ PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b), -+ PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79), -+ PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), -+ PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), -+ PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), -+ PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), -+ PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), -+ PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), -+ PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), -+ PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), -+ PCMCIA_DEVICE_NULL, -+}; -+ -+MODULE_DEVICE_TABLE(pcmcia, pcmcia_devices); -+ -+static struct pcmcia_driver pcmcia_driver = { -+ .owner = THIS_MODULE, -+ .drv { -+ .name = DRV_NAME, -+ }, -+ .id_table = pcmcia_devices, -+ .probe = pcmcia_init_one, -+ .remove = pcmcia_remove_one, -+ .suspend = pcmcia_suspend, -+ .resume = pcmcia_resume, -+}; -+ -+static int __init pcmcia_init(void) -+{ -+ return pcmcia_register_driver(&pcmcia_driver); -+} -+ -+static void __exit pcmcia_exit(void) -+{ -+ pcmcia_unregister_driver(&pcmcia_driver); -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for PCMCIA ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(pcmcia_init); -+module_exit(pcmcia_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_pdc2027x.c linux-2.6.16-rc2/drivers/scsi/pata_pdc2027x.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_pdc2027x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_pdc2027x.c 2006-01-21 16:56:47.000000000 +0000 -@@ -0,0 +1,857 @@ -+/* -+ * Promise PATA TX2/TX4/TX2000/133 IDE driver for pdc20268 to pdc20277. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Ported to libata by: -+ * Albert Lee <albertcc@tw.ibm.com> IBM Corporation -+ * -+ * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> -+ * Portions Copyright (C) 1999 Promise Technology, Inc. -+ * -+ * Author: Frank Tiernan (frankt@promise.com) -+ * Released under terms of General Public License -+ * -+ * -+ * libata documentation is available via 'make {ps|pdf}docs', -+ * as Documentation/DocBook/libata.* -+ * -+ * Hardware information only available under NDA. -+ * -+ */ -+#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/device.h> -+#include <scsi/scsi.h> -+#include <scsi/scsi_host.h> -+#include <scsi/scsi_cmnd.h> -+#include <linux/libata.h> -+#include <asm/io.h> -+ -+#define DRV_NAME "pata_pdc2027x" -+#define DRV_VERSION "0.73" -+#undef PDC_DEBUG -+ -+#ifdef PDC_DEBUG -+#define PDPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) -+#else -+#define PDPRINTK(fmt, args...) -+#endif -+ -+enum { -+ PDC_UDMA_100 = 0, -+ PDC_UDMA_133 = 1, -+ -+ PDC_100_MHZ = 100000000, -+ PDC_133_MHZ = 133333333, -+ -+ PDC_SYS_CTL = 0x1100, -+ PDC_ATA_CTL = 0x1104, -+ PDC_GLOBAL_CTL = 0x1108, -+ PDC_CTCR0 = 0x110C, -+ PDC_CTCR1 = 0x1110, -+ PDC_BYTE_COUNT = 0x1120, -+ PDC_PLL_CTL = 0x1202, -+}; -+ -+static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -+static void pdc2027x_remove_one(struct pci_dev *pdev); -+static void pdc2027x_phy_reset(struct ata_port *ap); -+static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev); -+static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev); -+static void pdc2027x_post_set_mode(struct ata_port *ap); -+static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc); -+ -+/* -+ * ATA Timing Tables based on 133MHz controller clock. -+ * These tables are only used when the controller is in 133MHz clock. -+ * If the controller is in 100MHz clock, the ASIC hardware will -+ * set the timing registers automatically when "set feature" command -+ * is issued to the device. However, if the controller clock is 133MHz, -+ * the following tables must be used. -+ */ -+static struct pdc2027x_pio_timing { -+ u8 value0, value1, value2; -+} pdc2027x_pio_timing_tbl [] = { -+ { 0xfb, 0x2b, 0xac }, /* PIO mode 0 */ -+ { 0x46, 0x29, 0xa4 }, /* PIO mode 1 */ -+ { 0x23, 0x26, 0x64 }, /* PIO mode 2 */ -+ { 0x27, 0x0d, 0x35 }, /* PIO mode 3, IORDY on, Prefetch off */ -+ { 0x23, 0x09, 0x25 }, /* PIO mode 4, IORDY on, Prefetch off */ -+}; -+ -+static struct pdc2027x_mdma_timing { -+ u8 value0, value1; -+} pdc2027x_mdma_timing_tbl [] = { -+ { 0xdf, 0x5f }, /* MDMA mode 0 */ -+ { 0x6b, 0x27 }, /* MDMA mode 1 */ -+ { 0x69, 0x25 }, /* MDMA mode 2 */ -+}; -+ -+static struct pdc2027x_udma_timing { -+ u8 value0, value1, value2; -+} pdc2027x_udma_timing_tbl [] = { -+ { 0x4a, 0x0f, 0xd5 }, /* UDMA mode 0 */ -+ { 0x3a, 0x0a, 0xd0 }, /* UDMA mode 1 */ -+ { 0x2a, 0x07, 0xcd }, /* UDMA mode 2 */ -+ { 0x1a, 0x05, 0xcd }, /* UDMA mode 3 */ -+ { 0x1a, 0x03, 0xcd }, /* UDMA mode 4 */ -+ { 0x1a, 0x02, 0xcb }, /* UDMA mode 5 */ -+ { 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */ -+}; -+ -+static const struct pci_device_id pdc2027x_pci_tbl[] = { -+#ifdef ATA_ENABLE_PATA -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20277, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, -+#endif -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver pdc2027x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = pdc2027x_pci_tbl, -+ .probe = pdc2027x_init_one, -+ .remove = __devexit_p(pdc2027x_remove_one), -+}; -+ -+static struct scsi_host_template pdc2027x_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 pdc2027x_pata100_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 = pdc2027x_phy_reset, -+ -+ .check_atapi_dma = pdc2027x_check_atapi_dma, -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_mmio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static struct ata_port_operations pdc2027x_pata133_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = pdc2027x_set_piomode, -+ .set_dmamode = pdc2027x_set_dmamode, -+ -+ .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 = pdc2027x_phy_reset, -+ .post_set_mode = pdc2027x_post_set_mode, -+ -+ .check_atapi_dma = pdc2027x_check_atapi_dma, -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_mmio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static struct ata_port_info pdc2027x_port_info[] = { -+ /* PDC_UDMA_100 */ -+ { -+ .sht = &pdc2027x_sht, -+ .host_flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | -+ ATA_FLAG_SRST | ATA_FLAG_MMIO, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = ATA_UDMA5, /* udma0-5 */ -+ .port_ops = &pdc2027x_pata100_ops, -+ }, -+ /* PDC_UDMA_133 */ -+ { -+ .sht = &pdc2027x_sht, -+ .host_flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | -+ ATA_FLAG_SRST | ATA_FLAG_MMIO, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = ATA_UDMA6, /* udma0-6 */ -+ .port_ops = &pdc2027x_pata133_ops, -+ }, -+}; -+ -+MODULE_AUTHOR("Andre Hedrick, Frank Tiernan, Albert Lee"); -+MODULE_DESCRIPTION("libata driver module for Promise PDC20268 to PDC20277"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); -+MODULE_DEVICE_TABLE(pci, pdc2027x_pci_tbl); -+ -+/** -+ * port_mmio - Get the MMIO address of PDC2027x extended registers -+ * @ap: Port -+ * @offset: offset from mmio base -+ */ -+static inline void* port_mmio(struct ata_port *ap, unsigned int offset) -+{ -+ return ap->host_set->mmio_base + ap->port_no * 0x100 + offset; -+} -+ -+/** -+ * dev_mmio - Get the MMIO address of PDC2027x extended registers -+ * @ap: Port -+ * @adev: device -+ * @offset: offset from mmio base -+ */ -+static inline void* dev_mmio(struct ata_port *ap, struct ata_device *adev, unsigned int offset) -+{ -+ u8 adj = (adev->devno) ? 0x08 : 0x00; -+ return port_mmio(ap, offset) + adj; -+} -+ -+/** -+ * pdc2027x_pata_cbl_detect - Probe host controller cable detect info -+ * @ap: Port for which cable detect info is desired -+ * -+ * Read 80c cable indicator from Promise extended register. -+ * This register is latched when the system is reset. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+static void pdc2027x_cbl_detect(struct ata_port *ap) -+{ -+ u32 cgcr; -+ -+ /* check cable detect results */ -+ cgcr = readl(port_mmio(ap, PDC_GLOBAL_CTL)); -+ if (cgcr & (1 << 26)) -+ goto cbl40; -+ -+ PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no); -+ -+ ap->cbl = ATA_CBL_PATA80; -+ return; -+ -+cbl40: -+ printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no); -+ ap->cbl = ATA_CBL_PATA40; -+ ap->udma_mask &= ATA_UDMA_MASK_40C; -+} -+ -+/** -+ * pdc2027x_port_enabled - Check PDC ATA control register to see whether the port is enabled. -+ * @ap: Port to check -+ */ -+static inline int pdc2027x_port_enabled(struct ata_port *ap) -+{ -+ return readb(port_mmio(ap, PDC_ATA_CTL)) & 0x02; -+} -+ -+/** -+ * pdc2027x_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * Probe PATA phy. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+static void pdc2027x_phy_reset(struct ata_port *ap) -+{ -+ /* Check whether port enabled */ -+ if (!pdc2027x_port_enabled(ap)) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ -+ pdc2027x_cbl_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * pdc2027x_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port to configure -+ * @adev: um -+ * @pio: PIO mode, 0 - 4 -+ * -+ * Set PIO mode for device. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int pio = adev->pio_mode - XFER_PIO_0; -+ u32 ctcr0, ctcr1; -+ -+ PDPRINTK("adev->pio_mode[%X]\n", adev->pio_mode); -+ -+ /* Sanity check */ -+ if (pio > 4) { -+ printk(KERN_ERR DRV_NAME ": Unknown pio mode [%d] ignored\n", pio); -+ return; -+ -+ } -+ -+ /* Set the PIO timing registers using value table for 133MHz */ -+ PDPRINTK("Set pio regs... \n"); -+ -+ ctcr0 = readl(dev_mmio(ap, adev, PDC_CTCR0)); -+ ctcr0 &= 0xffff0000; -+ ctcr0 |= pdc2027x_pio_timing_tbl[pio].value0 | -+ (pdc2027x_pio_timing_tbl[pio].value1 << 8); -+ writel(ctcr0, dev_mmio(ap, adev, PDC_CTCR0)); -+ -+ ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1)); -+ ctcr1 &= 0x00ffffff; -+ ctcr1 |= (pdc2027x_pio_timing_tbl[pio].value2 << 24); -+ writel(ctcr1, dev_mmio(ap, adev, PDC_CTCR1)); -+ -+ PDPRINTK("Set pio regs done\n"); -+ -+ PDPRINTK("Set to pio mode[%u] \n", pio); -+} -+ -+/** -+ * pdc2027x_set_dmamode - Initialize host controller PATA UDMA timings -+ * @ap: Port to configure -+ * @adev: um -+ * @udma: udma mode, XFER_UDMA_0 to XFER_UDMA_6 -+ * -+ * Set UDMA mode for device. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int dma_mode = adev->dma_mode; -+ u32 ctcr0, ctcr1; -+ -+ if ((dma_mode >= XFER_UDMA_0) && -+ (dma_mode <= XFER_UDMA_6)) { -+ /* Set the UDMA timing registers with value table for 133MHz */ -+ unsigned int udma_mode = dma_mode & 0x07; -+ -+ if (dma_mode == XFER_UDMA_2) { -+ /* -+ * Turn off tHOLD. -+ * If tHOLD is '1', the hardware will add half clock for data hold time. -+ * This code segment seems to be no effect. tHOLD will be overwritten below. -+ */ -+ ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1)); -+ writel(ctcr1 & ~(1 << 7), dev_mmio(ap, adev, PDC_CTCR1)); -+ } -+ -+ PDPRINTK("Set udma regs... \n"); -+ -+ ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1)); -+ ctcr1 &= 0xff000000; -+ ctcr1 |= pdc2027x_udma_timing_tbl[udma_mode].value0 | -+ (pdc2027x_udma_timing_tbl[udma_mode].value1 << 8) | -+ (pdc2027x_udma_timing_tbl[udma_mode].value2 << 16); -+ writel(ctcr1, dev_mmio(ap, adev, PDC_CTCR1)); -+ -+ PDPRINTK("Set udma regs done\n"); -+ -+ PDPRINTK("Set to udma mode[%u] \n", udma_mode); -+ -+ } else if ((dma_mode >= XFER_MW_DMA_0) && -+ (dma_mode <= XFER_MW_DMA_2)) { -+ /* Set the MDMA timing registers with value table for 133MHz */ -+ unsigned int mdma_mode = dma_mode & 0x07; -+ -+ PDPRINTK("Set mdma regs... \n"); -+ ctcr0 = readl(dev_mmio(ap, adev, PDC_CTCR0)); -+ -+ ctcr0 &= 0x0000ffff; -+ ctcr0 |= (pdc2027x_mdma_timing_tbl[mdma_mode].value0 << 16) | -+ (pdc2027x_mdma_timing_tbl[mdma_mode].value1 << 24); -+ -+ writel(ctcr0, dev_mmio(ap, adev, PDC_CTCR0)); -+ PDPRINTK("Set mdma regs done\n"); -+ -+ PDPRINTK("Set to mdma mode[%u] \n", mdma_mode); -+ } else { -+ printk(KERN_ERR DRV_NAME ": Unknown dma mode [%u] ignored\n", dma_mode); -+ } -+} -+ -+/** -+ * pdc2027x_post_set_mode - Set the timing registers back to correct values. -+ * @ap: Port to configure -+ * -+ * The pdc2027x hardware will look at "SET FEATURES" and change the timing registers -+ * automatically. The values set by the hardware might be incorrect, under 133Mhz PLL. -+ * This function overwrites the possibly incorrect values set by the hardware to be correct. -+ */ -+static void pdc2027x_post_set_mode(struct ata_port *ap) -+{ -+ int i; -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *dev = &ap->device[i]; -+ -+ if (ata_dev_present(dev)) { -+ -+ pdc2027x_set_piomode(ap, dev); -+ -+ /* -+ * Enable prefetch if the device support PIO only. -+ */ -+ if (dev->xfer_shift == ATA_SHIFT_PIO) { -+ u32 ctcr1 = readl(dev_mmio(ap, dev, PDC_CTCR1)); -+ ctcr1 |= (1 << 25); -+ writel(ctcr1, dev_mmio(ap, dev, PDC_CTCR1)); -+ -+ PDPRINTK("Turn on prefetch\n"); -+ } else { -+ pdc2027x_set_dmamode(ap, dev); -+ } -+ } -+ } -+} -+ -+/** -+ * pdc2027x_check_atapi_dma - Check whether ATAPI DMA can be supported for this command -+ * @qc: Metadata associated with taskfile to check -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ * -+ * RETURNS: 0 when ATAPI DMA can be used -+ * 1 otherwise -+ */ -+static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc) -+{ -+ struct scsi_cmnd *cmd = qc->scsicmd; -+ u8 *scsicmd = cmd->cmnd; -+ int rc = 1; /* atapi dma off by default */ -+ -+ /* -+ * This workaround is from Promise's GPL driver. -+ * If ATAPI DMA is used for commands not in the -+ * following white list, say MODE_SENSE and REQUEST_SENSE, -+ * pdc2027x might hit the irq lost problem. -+ */ -+ switch (scsicmd[0]) { -+ case READ_10: -+ case WRITE_10: -+ case READ_12: -+ case WRITE_12: -+ case READ_6: -+ case WRITE_6: -+ case 0xad: /* READ_DVD_STRUCTURE */ -+ case 0xbe: /* READ_CD */ -+ /* ATAPI DMA is ok */ -+ rc = 0; -+ break; -+ default: -+ ; -+ } -+ -+ return rc; -+} -+ -+/** -+ * pdc_read_counter - Read the ctr counter -+ * @probe_ent: for the port address -+ */ -+ -+static long pdc_read_counter(struct ata_probe_ent *probe_ent) -+{ -+ long counter; -+ int retry = 1; -+ u32 bccrl, bccrh, bccrlv, bccrhv; -+ -+retry: -+ bccrl = readl(probe_ent->mmio_base + PDC_BYTE_COUNT) & 0xffff; -+ bccrh = readl(probe_ent->mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff; -+ rmb(); -+ -+ /* Read the counter values again for verification */ -+ bccrlv = readl(probe_ent->mmio_base + PDC_BYTE_COUNT) & 0xffff; -+ bccrhv = readl(probe_ent->mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff; -+ rmb(); -+ -+ counter = (bccrh << 15) | bccrl; -+ -+ PDPRINTK("bccrh [%X] bccrl [%X]\n", bccrh, bccrl); -+ PDPRINTK("bccrhv[%X] bccrlv[%X]\n", bccrhv, bccrlv); -+ -+ /* -+ * The 30-bit decreasing counter are read by 2 pieces. -+ * Incorrect value may be read when both bccrh and bccrl are changing. -+ * Ex. When 7900 decrease to 78FF, wrong value 7800 might be read. -+ */ -+ if (retry && !(bccrh == bccrhv && bccrl >= bccrlv)) { -+ retry--; -+ PDPRINTK("rereading counter\n"); -+ goto retry; -+ } -+ -+ return counter; -+} -+ -+/** -+ * adjust_pll - Adjust the PLL input clock in Hz. -+ * -+ * @pdc_controller: controller specific information -+ * @probe_ent: For the port address -+ * @pll_clock: The input of PLL in HZ -+ */ -+static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsigned int board_idx) -+{ -+ -+ u16 pll_ctl; -+ long pll_clock_khz = pll_clock / 1000; -+ long pout_required = board_idx? PDC_133_MHZ:PDC_100_MHZ; -+ long ratio = pout_required / pll_clock_khz; -+ int F, R; -+ -+ /* Sanity check */ -+ if (unlikely(pll_clock_khz < 5000L || pll_clock_khz > 70000L)) { -+ printk(KERN_ERR DRV_NAME ": Invalid PLL input clock %ldkHz, give up!\n", pll_clock_khz); -+ return; -+ } -+ -+#ifdef PDC_DEBUG -+ PDPRINTK("pout_required is %ld\n", pout_required); -+ -+ /* Show the current clock value of PLL control register -+ * (maybe already configured by the firmware) -+ */ -+ pll_ctl = readw(probe_ent->mmio_base + PDC_PLL_CTL); -+ -+ PDPRINTK("pll_ctl[%X]\n", pll_ctl); -+#endif -+ -+ /* -+ * Calculate the ratio of F, R and OD -+ * POUT = (F + 2) / (( R + 2) * NO) -+ */ -+ if (ratio < 8600L) { /* 8.6x */ -+ /* Using NO = 0x01, R = 0x0D */ -+ R = 0x0d; -+ } else if (ratio < 12900L) { /* 12.9x */ -+ /* Using NO = 0x01, R = 0x08 */ -+ R = 0x08; -+ } else if (ratio < 16100L) { /* 16.1x */ -+ /* Using NO = 0x01, R = 0x06 */ -+ R = 0x06; -+ } else if (ratio < 64000L) { /* 64x */ -+ R = 0x00; -+ } else { -+ /* Invalid ratio */ -+ printk(KERN_ERR DRV_NAME ": Invalid ratio %ld, give up!\n", ratio); -+ return; -+ } -+ -+ F = (ratio * (R+2)) / 1000 - 2; -+ -+ if (unlikely(F < 0 || F > 127)) { -+ /* Invalid F */ -+ printk(KERN_ERR DRV_NAME ": F[%d] invalid!\n", F); -+ return; -+ } -+ -+ PDPRINTK("F[%d] R[%d] ratio*1000[%ld]\n", F, R, ratio); -+ -+ pll_ctl = (R << 8) | F; -+ -+ PDPRINTK("Writing pll_ctl[%X]\n", pll_ctl); -+ -+ writew(pll_ctl, probe_ent->mmio_base + PDC_PLL_CTL); -+ readw(probe_ent->mmio_base + PDC_PLL_CTL); /* flush */ -+ -+ /* Wait the PLL circuit to be stable */ -+ mdelay(30); -+ -+#ifdef PDC_DEBUG -+ /* -+ * Show the current clock value of PLL control register -+ * (maybe configured by the firmware) -+ */ -+ pll_ctl = readw(probe_ent->mmio_base + PDC_PLL_CTL); -+ -+ PDPRINTK("pll_ctl[%X]\n", pll_ctl); -+#endif -+ -+ return; -+} -+ -+/** -+ * detect_pll_input_clock - Detect the PLL input clock in Hz. -+ * @probe_ent: for the port address -+ * Ex. 16949000 on 33MHz PCI bus for pdc20275. -+ * Half of the PCI clock. -+ */ -+static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent) -+{ -+ u32 scr; -+ long start_count, end_count; -+ long pll_clock; -+ -+ /* Read current counter value */ -+ start_count = pdc_read_counter(probe_ent); -+ -+ /* Start the test mode */ -+ scr = readl(probe_ent->mmio_base + PDC_SYS_CTL); -+ PDPRINTK("scr[%X]\n", scr); -+ writel(scr | (0x01 << 14), probe_ent->mmio_base + PDC_SYS_CTL); -+ readl(probe_ent->mmio_base + PDC_SYS_CTL); /* flush */ -+ -+ /* Let the counter run for 100 ms. */ -+ mdelay(100); -+ -+ /* Read the counter values again */ -+ end_count = pdc_read_counter(probe_ent); -+ -+ /* Stop the test mode */ -+ scr = readl(probe_ent->mmio_base + PDC_SYS_CTL); -+ PDPRINTK("scr[%X]\n", scr); -+ writel(scr & ~(0x01 << 14), probe_ent->mmio_base + PDC_SYS_CTL); -+ readl(probe_ent->mmio_base + PDC_SYS_CTL); /* flush */ -+ -+ /* calculate the input clock in Hz */ -+ pll_clock = (start_count - end_count) * 10; -+ -+ PDPRINTK("start[%ld] end[%ld] \n", start_count, end_count); -+ PDPRINTK("PLL input clock[%ld]Hz\n", pll_clock); -+ -+ return pll_clock; -+} -+ -+/** -+ * pdc_hardware_init - Initialize the hardware. -+ * @pdev: instance of pci_dev found -+ * @pdc_controller: controller specific information -+ * @pe: for the port address -+ */ -+static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, unsigned int board_idx) -+{ -+ long pll_clock; -+ -+ /* -+ * Detect PLL input clock rate. -+ * On some system, where PCI bus is running at non-standard clock rate. -+ * Ex. 25MHz or 40MHz, we have to adjust the cycle_time. -+ * The pdc20275 controller employs PLL circuit to help correct timing registers setting. -+ */ -+ pll_clock = pdc_detect_pll_input_clock(pe); -+ -+ if (pll_clock < 0) /* counter overflow? Try again. */ -+ pll_clock = pdc_detect_pll_input_clock(pe); -+ -+ dev_printk(KERN_INFO, &pdev->dev, "PLL input clock %ld kHz\n", pll_clock/1000); -+ -+ /* Adjust PLL control register */ -+ pdc_adjust_pll(pe, pll_clock, board_idx); -+ -+ return 0; -+} -+ -+/** -+ * pdc_ata_setup_port - setup the mmio address -+ * @port: ata ioports to setup -+ * @base: base address -+ */ -+static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base) -+{ -+ port->cmd_addr = -+ port->data_addr = base; -+ port->feature_addr = -+ port->error_addr = base + 0x05; -+ port->nsect_addr = base + 0x0a; -+ port->lbal_addr = base + 0x0f; -+ port->lbam_addr = base + 0x10; -+ port->lbah_addr = base + 0x15; -+ port->device_addr = base + 0x1a; -+ port->command_addr = -+ port->status_addr = base + 0x1f; -+ port->altstatus_addr = -+ port->ctl_addr = base + 0x81a; -+} -+ -+/** -+ * pdc2027x_init_one - PCI probe function -+ * Called when an instance of PCI adapter is inserted. -+ * This function checks whether the hardware is supported, -+ * initialize hardware and register an instance of ata_host_set to -+ * libata by providing struct ata_probe_ent and ata_device_add(). -+ * (implements struct pci_driver.probe() ) -+ * -+ * @pdev: instance of pci_dev found -+ * @ent: matching entry in the id_tbl[] -+ */ -+static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ unsigned int board_idx = (unsigned int) ent->driver_data; -+ -+ struct ata_probe_ent *probe_ent = NULL; -+ unsigned long base; -+ void *mmio_base; -+ int rc; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, "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; -+ -+ 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; -+ -+ /* Prepare the probe entry */ -+ 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, 5), -+ pci_resource_len(pdev, 5)); -+ -+ if (mmio_base == NULL) { -+ rc = -ENOMEM; -+ goto err_out_free_ent; -+ } -+ -+ base = (unsigned long) mmio_base; -+ -+ probe_ent->sht = pdc2027x_port_info[board_idx].sht; -+ probe_ent->host_flags = pdc2027x_port_info[board_idx].host_flags; -+ probe_ent->pio_mask = pdc2027x_port_info[board_idx].pio_mask; -+ probe_ent->mwdma_mask = pdc2027x_port_info[board_idx].mwdma_mask; -+ probe_ent->udma_mask = pdc2027x_port_info[board_idx].udma_mask; -+ probe_ent->port_ops = pdc2027x_port_info[board_idx].port_ops; -+ -+ probe_ent->irq = pdev->irq; -+ probe_ent->irq_flags = SA_SHIRQ; -+ probe_ent->mmio_base = mmio_base; -+ -+ pdc_ata_setup_port(&probe_ent->port[0], base + 0x17c0); -+ probe_ent->port[0].bmdma_addr = base + 0x1000; -+ pdc_ata_setup_port(&probe_ent->port[1], base + 0x15c0); -+ probe_ent->port[1].bmdma_addr = base + 0x1008; -+ -+ probe_ent->n_ports = 2; -+ -+ pci_set_master(pdev); -+ //pci_enable_intx(pdev); -+ -+ /* initialize adapter */ -+ if (pdc_hardware_init(pdev, probe_ent, board_idx) != 0) -+ goto err_out_free_ent; -+ -+ ata_device_add(probe_ent); -+ kfree(probe_ent); -+ -+ return 0; -+ -+err_out_free_ent: -+ kfree(probe_ent); -+err_out_regions: -+ pci_release_regions(pdev); -+err_out: -+ pci_disable_device(pdev); -+ return rc; -+} -+ -+/** -+ * pdc2027x_remove_one - Called to remove a single instance of the -+ * adapter. -+ * -+ * @dev: The PCI device to remove. -+ * FIXME: module load/unload not working yet -+ */ -+static void __devexit pdc2027x_remove_one(struct pci_dev *pdev) -+{ -+ ata_pci_remove_one(pdev); -+} -+ -+/** -+ * pdc2027x_init - Called after this module is loaded into the kernel. -+ */ -+static int __init pdc2027x_init(void) -+{ -+ return pci_register_driver(&pdc2027x_pci_driver); -+} -+ -+/** -+ * pdc2027x_exit - Called before this module unloaded from the kernel -+ */ -+static void __exit pdc2027x_exit(void) -+{ -+ pci_unregister_driver(&pdc2027x_pci_driver); -+} -+ -+module_init(pdc2027x_init); -+module_exit(pdc2027x_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_qdi.c linux-2.6.16-rc2/drivers/scsi/pata_qdi.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_qdi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_qdi.c 2006-01-21 20:43:47.000000000 +0000 -@@ -0,0 +1,367 @@ -+/* -+ * pata_qdi.c - QDI VLB ATA controllers -+ * (C) 2006 Red Hat <alan@redhat.com> -+ * -+ * This driver mostly exists as a proof of concept for non PCI devices under libata. -+ * While the QDI6580 was 'neat' in 1993 it is no longer terribly useful. -+ * -+ * Tuning code written from the documentation at -+ * http://www.ryston.cz/petr/vlb/qd6500.html -+ * http://www.ryston.cz/petr/vlb/qd6580.html -+ * -+ * Probe code based on drivers/ide/legacy/qd65xx.c -+ * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by -+ * Samuel Thibault <samuel.thibault@fnac.net> -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_qdi" -+#define DRV_VERSION "0.1" -+ -+#define NR_HOST 4 /* Two 6580s */ -+ -+struct qdi_data { -+ unsigned long timing; -+ u8 clock[2]; -+ u8 last; -+ int fast; -+ -+}; -+ -+static struct ata_host_set *qdi_host[NR_HOST]; -+static struct qdi_data qdi_data[NR_HOST]; -+static int nr_qdi_host = 0; -+ -+static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct ata_timing t; -+ struct qdi_data *qdi = ap->host_set->private_data; -+ int active, recovery; -+ u8 timing; -+ -+ /* Get the timing data in cycles */ -+ ata_timing_compute(adev, adev->pio_mode, &t, 33000, 1000); -+ -+ if (qdi->fast) { -+ active = 8 - FIT(t.active, 1, 8); -+ recovery = 18 - FIT(t.recover, 3, 18); -+ } else { -+ active = 9 - FIT(t.active, 2, 9); -+ recovery = 15 - FIT(t.recover, 0, 15); -+ } -+ timing = (recovery << 4) | active | 0x08; -+ -+ qdi->clock[adev->devno] = timing; -+ -+ outb(timing, qdi->timing); -+} -+ -+static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct ata_timing t; -+ struct qdi_data *qdi = ap->host_set->private_data; -+ int active, recovery; -+ u8 timing; -+ -+ /* Get the timing data in cycles */ -+ ata_timing_compute(adev, adev->pio_mode, &t, 33, 1000); -+ -+ if (qdi->fast) { -+ active = 8 - FIT(t.active, 1, 8); -+ recovery = 18 - FIT(t.recover, 3, 18); -+ } else { -+ active = 9 - FIT(t.active, 2, 9); -+ recovery = 15 - FIT(t.recover, 0, 15); -+ } -+ timing = (recovery << 4) | active | 0x08; -+ -+ qdi->clock[adev->devno] = timing; -+ -+ outb(timing, qdi->timing); -+ -+ /* Clear the FIFO */ -+ if (adev->class != ATA_DEV_ATA) -+ outb(0x5F, (qdi->timing & 0xFFF0) + 3); -+} -+ -+/** -+ * qdi_qc_issue_prot - command issue -+ * @qc: command pending -+ * -+ * Called when the libata layer is about to issue a command. We wrap -+ * this interface so that we can load the correct ATA timings. -+ */ -+ -+static int qdi_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ struct qdi_data *qdi = ap->host_set->private_data; -+ -+ if (qdi->clock[adev->devno] != qdi->last) { -+ if (adev->pio_mode) { -+ qdi->last = qdi->clock[adev->devno]; -+ outb(qdi->clock[adev->devno], qdi->timing); -+ } -+ } -+ return ata_qc_issue_prot(qc); -+} -+ -+static void qdi_data_xfer(struct ata_port *ap, unsigned char *buf, unsigned int buflen, int write_data) -+{ -+ int slop = buflen & 3; -+ -+ if (write_data) -+ outsl(ap->ioaddr.data_addr, buf, buflen >> 2); -+ else -+ insl(ap->ioaddr.data_addr, buf, buflen >> 2); -+ -+ if (unlikely(slop)) { -+ u32 pad; -+ if (write_data) { -+ memcpy(&pad, buf + buflen - slop, slop); -+ outl(le32_to_cpu(pad), ap->ioaddr.data_addr); -+ } else { -+ pad = cpu_to_le16(inl(ap->ioaddr.data_addr)); -+ memcpy(buf + buflen - slop, &pad, slop); -+ } -+ } -+} -+ -+static struct scsi_host_template qdi_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations qdi6500_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = qdi6500_set_piomode, -+ -+ .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, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = qdi_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = qdi_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations qdi6580_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = qdi6580_set_piomode, -+ -+ .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, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = qdi_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = qdi_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * qdi_init_one - attach a qdi interface -+ * @type: Type to display -+ * @io: I/O port start -+ * @irq: interrupt line -+ * @fast: True if on a > 33Mhz VLB -+ * -+ * Register an ISA bus IDE interface. Such interfaces are PIO and we -+ * assume do not support IRQ sharing. -+ */ -+ -+static __init int qdi_init_one(unsigned long port, int type, unsigned long io, int irq, int fast) -+{ -+ struct ata_probe_ent ae; -+ int ret; -+ -+ unsigned long ctrl = io + 0x206; -+ -+ /* -+ * Fill in a probe structure first of all -+ */ -+ -+ memset(&ae, 0, sizeof(struct ata_probe_ent)); -+ INIT_LIST_HEAD(&ae.node); -+ ae.dev = NULL; -+ -+ if (type == 6580) { -+ ae.port_ops = &qdi6580_port_ops; -+ ae.pio_mask = 0x1F; -+ } else { -+ ae.port_ops = &qdi6500_port_ops; -+ ae.pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */ -+ } -+ -+ ae.sht = &qdi_sht; -+ ae.n_ports = 1; -+ ae.irq = irq; -+ ae.irq_flags = 0; -+ ae.host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_IRQ_MASK; -+ ae.port[0].cmd_addr = io; -+ ae.port[0].altstatus_addr = ctrl; -+ ae.port[0].ctl_addr = ctrl; -+ ata_std_ports(&ae.port[0]); -+ -+ /* -+ * Hook in a private data structure per channel -+ */ -+ ae.private_data = &qdi_data[nr_qdi_host]; -+ -+ qdi_data[nr_qdi_host].timing = port; -+ qdi_data[nr_qdi_host].fast = fast; -+ -+ printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io); -+ ret = ata_device_add(&ae); -+ if (ret == 0) -+ return -ENODEV; -+ -+ qdi_host[nr_qdi_host++] = ae.host_set; -+ return 0; -+} -+ -+/** -+ * qdi_init - attach qdi interfaces -+ * -+ * Attach qdi IDE interfaces by scanning the ports it may occupy. -+ */ -+ -+static __init int qdi_init(void) -+{ -+ unsigned long flags; -+ unsigned long qd_port[2] = { 0x30, 0xB0 }; -+ unsigned long ide_port[2] = { 0x170, 0x1F0 }; -+ int ide_irq[2] = { 14, 15 }; -+ int ct = 0; -+ int i; -+ -+ /* -+ * Check each possible QD65xx base address -+ */ -+ -+ for (i = 0; i < 2; i++) { -+ unsigned long port = qd_port[i]; -+ u8 r, res; -+ -+ -+ if (request_region(port, 2, "pata_qdi")) { -+ /* Check for a card */ -+ local_irq_save(flags); -+ r = inb_p(port); -+ outb_p(0x19, port); -+ res = inb_p(port); -+ outb_p(r, port); -+ local_irq_restore(flags); -+ -+ /* Fail */ -+ if (res == 0x19) -+ { -+ release_region(port, 2); -+ continue; -+ } -+ -+ /* Passes the presence test */ -+ r = inb_p(port + 1); /* Check port agrees with port set */ -+ if ((r & 2) >> 1 != i) { -+ release_region(port, 2); -+ continue; -+ } -+ -+ /* Check card type */ -+ if ((r & 0xF0) == 0xC0) { -+ /* QD6500: single channel */ -+ if (r & 8) { -+ /* Disabled ? */ -+ release_region(port, 2); -+ continue; -+ } -+ ct += qdi_init_one(port, 6500, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04); -+ } -+ if (((r & 0xF0) == 0xA0) || (r & 0xF0) == 0x50) { -+ /* QD6580: dual channel */ -+ if (!request_region(port + 2 , 2, "pata_qdi")) -+ { -+ release_region(port, 2); -+ continue; -+ } -+ res = inb(port + 3); -+ if (res & 1) { -+ /* Single channel mode */ -+ ct += qdi_init_one(port, 6580, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04); -+ } else { -+ /* Dual channel mode */ -+ ct += qdi_init_one(port, 6580, 0x1F0, 14, r & 0x04); -+ ct += qdi_init_one(port + 2, 6580, 0x170, 15, r & 0x04); -+ } -+ } -+ } -+ } -+ if (ct != 0) -+ return 0; -+ return -ENODEV; -+} -+ -+static __exit void qdi_exit(void) -+{ -+ int i; -+ -+ for (i = 0; i < nr_qdi_host; i++) { -+ ata_host_set_remove(qdi_host[i]); -+ /* Free the control resource. The 6580 dual channel has the resources -+ * claimed as a pair of 2 byte resources so we need no special cases... -+ */ -+ release_region(qdi_data[i].timing, 2); -+ } -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for qdi ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(qdi_init); -+module_exit(qdi_exit); -+ -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_rz1000.c linux-2.6.16-rc2/drivers/scsi/pata_rz1000.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_rz1000.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_rz1000.c 2006-02-07 13:37:54.369769928 +0000 -@@ -0,0 +1,183 @@ -+/* -+ * RZ1000/1001 driver based upon -+ * -+ * linux/drivers/ide/pci/rz1000.c Version 0.06 January 12, 2003 -+ * Copyright (C) 1995-1998 Linus Torvalds & author (see below) -+ * Principal Author: mlord@pobox.com (Mark Lord) -+ * -+ * See linux/MAINTAINERS for address of current maintainer. -+ * -+ * This file provides support for disabling the buggy read-ahead -+ * mode of the RZ1000 IDE chipset, commonly used on Intel motherboards. -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "rz1000" -+#define DRV_VERSION "0.01" -+ -+static void rz1000_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * rz1000_set_mode - mode setting function -+ * @ap: ATA interface -+ * -+ * Use a non standard set_mode function. We don't want to be tuned. We -+ * would prefer to be BIOS generic but for the fact our hardware is -+ * whacked out. -+ */ -+ -+static void rz1000_set_mode(struct ata_port *ap) -+{ -+ int i; -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *dev = &ap->device[i]; -+ if (ata_dev_present(dev)) { -+ /* We don't really care */ -+ dev->pio_mode = XFER_PIO_0; -+ dev->xfer_mode = XFER_PIO_0; -+ dev->xfer_shift = ATA_SHIFT_PIO; -+ dev->flags |= ATA_DFLAG_PIO; -+ } -+ } -+} -+ -+ -+static struct scsi_host_template rz1000_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations rz1000_port_ops = { -+ .set_mode = rz1000_set_mode, -+ -+ .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 = rz1000_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * rz1000_init_one - Register RZ1000 ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in rz1000_pci_tbl matching with @pdev -+ * -+ * Configure an RZ1000 interface. This doesn't require much special -+ * handling except that we *MUST* kill the chipset readahead or the -+ * user may experience data corruption. -+ */ -+ -+static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ struct ata_port_info *port_info[2]; -+ u16 reg; -+ static struct ata_port_info info = { -+ .sht = &rz1000_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .port_ops = &rz1000_port_ops -+ }; -+ -+ if (!printed_version++) -+ printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); -+ -+ /* Be exceptionally paranoid as we must be sure to apply the fix */ -+ if(pci_read_config_word(pdev, 0x40, ®) != 0) -+ goto fail; -+ reg &= 0xDFFF; -+ if(pci_write_config_word(pdev, 0x40, reg) != 0) -+ goto fail; -+ printk(KERN_INFO DRV_NAME ": disabled chipset readahead.\n"); -+ -+ port_info[0] = &info; -+ port_info[1] = &info; -+ return ata_pci_init_one(pdev, port_info, 2); -+fail: -+ printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n"); -+ /* Not safe to use so skip */ -+ return -ENODEV; -+} -+ -+static struct pci_device_id pata_rz1000[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), }, -+ { 0, }, -+}; -+ -+static struct pci_driver rz1000_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = pata_rz1000, -+ .probe = rz1000_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+ -+static int __init rz1000_init(void) -+{ -+ return pci_register_driver(&rz1000_pci_driver); -+} -+ -+static void __exit rz1000_exit(void) -+{ -+ pci_unregister_driver(&rz1000_pci_driver); -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for RZ1000 PCI ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, pata_rz1000); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(rz1000_init); -+module_exit(rz1000_exit); -+ -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_sc1200.c linux-2.6.16-rc2/drivers/scsi/pata_sc1200.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_sc1200.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_sc1200.c 2006-02-07 13:39:25.938849312 +0000 -@@ -0,0 +1,264 @@ -+/* -+ * New ATA layer SC1200 driver Alan Cox <alan@redhat.com> -+ * -+ * TODO: Mode selection filtering -+ * TODO: Can't enable second channel until ATA core has serialize -+ * TODO: Needs custom DMA cleanup code -+ * -+ * Based very heavily on -+ * -+ * linux/drivers/ide/pci/sc1200.c Version 0.91 28-Jan-2003 -+ * -+ * Copyright (C) 2000-2002 Mark Lord <mlord@pobox.com> -+ * May be copied or modified under the terms of the GNU General Public License -+ * -+ * Development of this chipset driver was funded -+ * by the nice folks at National Semiconductor. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "sc1200" -+#define DRV_VERSION "0.1" -+ -+#define SC1200_REV_A 0x00 -+#define SC1200_REV_B1 0x01 -+#define SC1200_REV_B3 0x02 -+#define SC1200_REV_C1 0x03 -+#define SC1200_REV_D1 0x04 -+ -+/** -+ * sc1200_clock - PCI clock -+ * -+ * Return the PCI bus clocking for the SC1200 chipset configuration -+ * in use. We return 0 for 33MHz 1 for 48MHz and 2 for 66Mhz -+ */ -+ -+static int sc1200_clock(void) -+{ -+ /* Magic registers that give us the chipset data */ -+ u8 chip_id = inb(0x903C); -+ u8 silicon_rev = inb(0x903D); -+ u16 pci_clock; -+ -+ if(chip_id == 0x04 && silicon_rev < SC1200_REV_B1) -+ return 0; /* 33 MHz mode */ -+ -+ /* Clock generator configuration 0x901E its 8/9 are the PCI clocking -+ 0/3 is 33Mhz 1 is 48 2 is 66 */ -+ -+ pci_clock = inw(0x901E); -+ pci_clock >>= 8; -+ pci_clock &= 0x03; -+ if(pci_clock == 3) -+ pci_clock = 0; -+ return pci_clock; -+} -+ -+/** -+ * sc1200_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Set our PIO requirements. This is fairly simple on the SC1200 -+ */ -+ -+static void sc1200_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u32 pio_timings[4][5] = { -+ {0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010}, // format0 33Mhz -+ {0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010}, // format1, 33Mhz -+ {0xfaa3f4f3, 0xc23232b2, 0x513101c1, 0x31213121, 0x10211021}, // format1, 48Mhz -+ {0xfff4fff4, 0xf35353d3, 0x814102f1, 0x42314231, 0x11311131} // format1, 66Mhz -+ }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 format; -+ unsigned int reg = 0x40 + 0x10 * ap->hard_port_no; -+ int mode = adev->pio_mode - XFER_PIO_0; -+ -+ pci_read_config_dword(pdev, reg + 4, &format); -+ format >>= 31; -+ format += sc1200_clock(); -+ pci_write_config_dword(pdev, reg + 8 * adev->devno, -+ pio_timings[format][mode]); -+} -+ -+/** -+ * sc1200_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * We cannot mix MWDMA and UDMA without reloading timings each switch -+ * master to slave. We should implement the switch but for now we follow -+ * the old IDE driver and just avoid setting such combinations. -+ * -+ * This will come up once the SATA core grows up and develops proper -+ * timing code. -+ */ -+ -+static void sc1200_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u32 udma_timing[3][3] = { -+ { 0x00921250, 0x00911140, 0x00911030 }, -+ { 0x00932470, 0x00922260, 0x00922140 }, -+ { 0x009436A1, 0x00933481, 0x00923261 } -+ }; -+ -+ static u32 mwdma_timing[3][3] = { -+ { 0x00077771, 0x00012121, 0x00002020 }, -+ { 0x000BBBB2, 0x00024241, 0x00013131 }, -+ { 0x000FFFF3, 0x00035352, 0x00015151 } -+ }; -+ -+ int clock = sc1200_clock(); -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ unsigned int reg = 0x40 + 0x10 * ap->hard_port_no; -+ int mode = adev->dma_mode; -+ u32 format; -+ -+ if(mode >= XFER_UDMA_0) -+ format = udma_timing[clock][mode - XFER_UDMA_0]; -+ else -+ format = mwdma_timing[clock][mode - XFER_MW_DMA_0]; -+ -+ if(adev->devno == 0) { -+ u32 timings; -+ -+ pci_read_config_dword(pdev, reg + 4, &timings); -+ timings &= 0x80000000UL; -+ timings |= format; -+ pci_write_config_dword(pdev, reg + 4, timings); -+ } else -+ pci_write_config_dword(pdev, reg + 12, format); -+} -+ -+static struct scsi_host_template sc1200_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations sc1200_port_ops = { -+/* .set_mode = sc1200_set_mode, FIXME - for master/slave */ -+ -+ .port_disable = ata_port_disable, -+ .set_piomode = sc1200_set_piomode, -+ .set_dmamode = sc1200_set_dmamode, -+ -+ .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, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * sc1200_init_one - Initialise an SC1200 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Just throw the needed data at the libata helper and it does all -+ * our work. -+ */ -+ -+static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &sc1200_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x07, -+ .port_ops = &sc1200_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ /* Can't enable port 2 yet, see top comments */ -+ return ata_pci_init_one(dev, port_info, 1); -+} -+ -+static struct pci_device_id sc1200[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE), }, -+ { 0, }, -+}; -+ -+static struct pci_driver sc1200_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = sc1200, -+ .probe = sc1200_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init sc1200_init(void) -+{ -+ return pci_register_driver(&sc1200_pci_driver); -+} -+ -+ -+static void __exit sc1200_exit(void) -+{ -+ pci_unregister_driver(&sc1200_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox, Mark Lord"); -+MODULE_DESCRIPTION("low-level driver for the NS/AMD SC1200"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, sc1200); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(sc1200_init); -+module_exit(sc1200_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_serverworks.c linux-2.6.16-rc2/drivers/scsi/pata_serverworks.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_serverworks.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_serverworks.c 2006-02-07 13:38:36.921301112 +0000 -@@ -0,0 +1,591 @@ -+/* -+ * ata-serverworks.c - Serverworks PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon -+ * -+ * serverworks.c -+ * -+ * Copyright (C) 1998-2000 Michel Aubry -+ * Copyright (C) 1998-2000 Andrzej Krzysztofowicz -+ * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> -+ * Portions copyright (c) 2001 Sun Microsystems -+ * -+ * -+ * RCC/ServerWorks IDE driver for Linux -+ * -+ * OSB4: `Open South Bridge' IDE Interface (fn 1) -+ * supports UDMA mode 2 (33 MB/s) -+ * -+ * CSB5: `Champion South Bridge' IDE Interface (fn 1) -+ * all revisions support UDMA mode 4 (66 MB/s) -+ * revision A2.0 and up support UDMA mode 5 (100 MB/s) -+ * -+ * *** The CSB5 does not provide ANY register *** -+ * *** to detect 80-conductor cable presence. *** -+ * -+ * CSB6: `Champion South Bridge' IDE Interface (optional: third channel) -+ * -+ * Documentation: -+ * Available under NDA only. Errata info very hard to get. -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "serverworks" -+#define DRV_VERSION "0.1.1" -+ -+#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */ -+#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */ -+ -+/* Seagate Barracuda ATA IV Family drives in UDMA mode 5 -+ * can overrun their FIFOs when used with the CSB5 */ -+ -+static const char *csb_bad_ata100[] = { -+ "ST320011A", -+ "ST340016A", -+ "ST360021A", -+ "ST380021A", -+ NULL -+}; -+ -+/** -+ * dell_cable - Dell serverworks cable detection -+ * @ap: ATA port to do cable detect -+ * -+ * Dell hide the 40/80 pin select for their interfaces in the top two -+ * bits of the subsystem ID. -+ */ -+ -+static int dell_cable(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ if (pdev->subsystem_device & (1 << (ap->hard_port_no + 14))) -+ return ATA_CBL_PATA80; -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * sun_cable - Sun Cobalt 'Alpine' cable detection -+ * @ap: ATA port to do cable select -+ * -+ * Cobalt CSB5 IDE hides the 40/80pin in the top two bits of the -+ * subsystem ID the same as dell. We could use one function but we may -+ * need to extend the Dell one in future -+ */ -+ -+static int sun_cable(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ if (pdev->subsystem_device & (1 << (ap->hard_port_no + 14))) -+ return ATA_CBL_PATA80; -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * osb4_cable - OSB4 cable detect -+ * @ap: ATA port to check -+ * -+ * The OSB4 isn't UDMA66 capable so this is easy -+ */ -+ -+static int osb4_cable(struct ata_port *ap) { -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * csb4_cable - CSB5/6 cable detect -+ * @ap: ATA port to check -+ * -+ * Serverworks default arrangement is to use the drive side detection -+ * only. -+ */ -+ -+static int csb_cable(struct ata_port *ap) { -+ return ATA_CBL_PATA80; -+} -+ -+struct sv_cable_table { -+ int device; -+ int subvendor; -+ int (*cable_detect)(struct ata_port *ap); -+}; -+ -+/* -+ * Note that we don't copy the old serverworks code because the old -+ * code contains obvious mistakes -+ */ -+ -+static struct sv_cable_table cable_detect[] = { -+ { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_DELL, dell_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_VENDOR_ID_DELL, dell_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_SUN, sun_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_OSB4, PCI_ANY_ID, osb4_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, csb_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, csb_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, csb_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, csb_cable }, -+ { } -+}; -+ -+/** -+ * serverworks_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection according to the device and subvendor -+ * identifications -+ */ -+ -+static int serverworks_cable_detect(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct sv_cable_table *cb = cable_detect; -+ -+ while(cb->device) { -+ if(cb->device == pdev->device && -+ (cb->subvendor == pdev->subsystem_vendor || -+ cb->subvendor == PCI_ANY_ID)) { -+ return cb->cable_detect(ap); -+ } -+ cb++; -+ } -+ BUG(); -+} -+ -+static void serverworks_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = serverworks_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * serverworks_is_csb - Check for CSB or OSB -+ * @pdev: PCI device to check -+ * -+ * Returns true if the device being checked is known to be a CSB -+ * series device. -+ */ -+ -+static u8 serverworks_is_csb(struct pci_dev *pdev) -+{ -+ switch (pdev->device) { -+ case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: -+ case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE: -+ case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2: -+ case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE: -+ return 1; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+/** -+ * serverworks_osb4_filter - mode selection filter -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Filter the offered modes for the device to apply controller -+ * specific rules. OSB4 requires no UDMA for disks due to a FIFO -+ * bug we hit. -+ */ -+ -+static unsigned int serverworks_osb4_filter(const struct ata_port *ap, struct ata_device *adev, unsigned int mask, int shift) -+{ -+ if(shift != ATA_SHIFT_UDMA) -+ return mask; -+ if(adev->class == ATA_DEV_ATA) -+ return 0; -+ return mask; -+} -+ -+ -+/** -+ * serverworks_csb_filter - mode selection filter -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Check the blacklist and disable UDMA5 if matched -+ */ -+ -+static unsigned int serverworks_csb_filter(const struct ata_port *ap, struct ata_device *adev, unsigned int mask, int shift) -+{ -+ const char *p; -+ char model_num[40]; -+ int len, i; -+ -+ /* Disk, UDMA */ -+ if(shift != ATA_SHIFT_UDMA) -+ return mask; -+ if(adev->class != ATA_DEV_ATA) -+ return mask; -+ -+ /* Actually do need to check */ -+ ata_dev_id_string(adev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num)); -+ /* Precuationary - why not do this in the libata core ?? */ -+ -+ len = strlen(model_num); -+ while ((len > 0) && (model_num[len - 1] == ' ')) { -+ len--; -+ model_num[len] = 0; -+ } -+ -+ for(i = 0; (p = csb_bad_ata100[i]) != NULL; i++) { -+ if (!strncmp(p, model_num, len)) -+ return mask & 0x1F; -+ } -+ return mask; -+} -+ -+ -+/** -+ * serverworks_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the OSB4/CSB5 timing registers for PIO. The PIO register -+ * load is done as a simple lookup. -+ */ -+static void serverworks_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u8 pio_mode[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; -+ int offset = 1 + 2 * ap->hard_port_no - adev->devno; -+ int devbits = (2 * ap->hard_port_no + adev->devno) * 4; -+ u16 csb5_pio; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int pio = adev->pio_mode - XFER_PIO_0; -+ -+ pci_write_config_byte(pdev, 0x40 + offset, pio_mode[pio]); -+ -+ /* The OSB4 just requires the timing but the CSB series want the -+ mode number as well */ -+ if(serverworks_is_csb(pdev)) { -+ pci_read_config_word(pdev, 0x4A, &csb5_pio); -+ csb5_pio &= ~(0x0F << devbits); -+ pci_write_config_byte(pdev, 0x4A, csb5_pio | (pio << devbits)); -+ } -+} -+ -+/** -+ * serverworks_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the MWDMA/UDMA modes for the serverworks OSB4/CSB5 -+ * chipset. The MWDMA mode values are pulled from a lookup table -+ * while the chipset uses mode number for UDMA. -+ */ -+ -+static void serverworks_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u8 dma_mode[] = { 0x77, 0x21, 0x20 }; -+ int offset = 1 + 2 * ap->hard_port_no - adev->devno; -+ int devbits = (2 * ap->hard_port_no + adev->devno); -+ u8 ultra; -+ u8 ultra_cfg; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_byte(pdev, 0x54, &ultra_cfg); -+ -+ if(adev->dma_mode >= XFER_UDMA_0) { -+ pci_write_config_byte(pdev, 0x44 + offset, 0x20); -+ -+ pci_read_config_byte(pdev, 0x56 + ap->hard_port_no, &ultra); -+ ultra &= ~(0x0F << (ap->hard_port_no * 4)); -+ ultra |= (adev->dma_mode - XFER_UDMA_0) -+ << (ap->hard_port_no * 4); -+ pci_write_config_byte(pdev, 0x56 + ap->hard_port_no, ultra); -+ -+ ultra_cfg |= (1 << devbits); -+ } else { -+ pci_write_config_byte(pdev, 0x44 + offset, -+ dma_mode[adev->dma_mode - XFER_MW_DMA_0]); -+ ultra_cfg &= ~(1 << devbits); -+ } -+ pci_write_config_byte(pdev, 0x54, ultra_cfg); -+} -+ -+static struct scsi_host_template serverworks_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations serverworks_osb4_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = serverworks_set_piomode, -+ .set_dmamode = serverworks_set_dmamode, -+ .mode_filter = serverworks_osb4_filter, -+ -+ .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 = serverworks_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations serverworks_csb_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = serverworks_set_piomode, -+ .set_dmamode = serverworks_set_dmamode, -+ .mode_filter = serverworks_csb_filter, -+ -+ .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 = serverworks_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int serverworks_fixup_osb4(struct pci_dev *pdev) -+{ -+ u32 reg; -+ struct pci_dev *isa_dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, -+ PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL); -+ if (isa_dev) { -+ pci_read_config_dword(isa_dev, 0x64, ®); -+ reg &= ~0x00002000; /* disable 600ns interrupt mask */ -+ if(!(reg & 0x00004000)) -+ printk(KERN_DEBUG DRV_NAME ": UDMA not BIOS enabled.\n"); -+ reg |= 0x00004000; /* enable UDMA/33 support */ -+ pci_write_config_dword(isa_dev, 0x64, reg); -+ pci_dev_put(isa_dev); -+ return 0; -+ } -+ printk(KERN_WARNING "ata_serverworks: Unable to find bridge.\n"); -+ return -ENODEV; -+} -+ -+static int serverworks_fixup_csb(struct pci_dev *pdev) -+{ -+ u8 rev; -+ u8 btr; -+ -+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); -+ -+ /* Third Channel Test */ -+ if (!(PCI_FUNC(pdev->devfn) & 1)) { -+ struct pci_dev * findev = NULL; -+ u32 reg4c = 0; -+ findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, -+ PCI_DEVICE_ID_SERVERWORKS_CSB5, NULL); -+ if (findev) { -+ pci_read_config_dword(findev, 0x4C, ®4c); -+ reg4c &= ~0x000007FF; -+ reg4c |= 0x00000040; -+ reg4c |= 0x00000020; -+ pci_write_config_dword(findev, 0x4C, reg4c); -+ pci_dev_put(findev); -+ } -+#if 0 -+FIXME -+ outb_p(0x06, 0x0c00); -+ dev->irq = inb_p(0x0c01); -+#endif -+ } else { -+ struct pci_dev * findev = NULL; -+ u8 reg41 = 0; -+ -+ findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, -+ PCI_DEVICE_ID_SERVERWORKS_CSB6, NULL); -+ if (findev) { -+ pci_read_config_byte(findev, 0x41, ®41); -+ reg41 &= ~0x40; -+ pci_write_config_byte(findev, 0x41, reg41); -+ pci_dev_put(findev); -+ } -+ } -+ /* setup the UDMA Control register -+ * -+ * 1. clear bit 6 to enable DMA -+ * 2. enable DMA modes with bits 0-1 -+ * 00 : legacy -+ * 01 : udma2 -+ * 10 : udma2/udma4 -+ * 11 : udma2/udma4/udma5 -+ */ -+ pci_read_config_byte(pdev, 0x5A, &btr); -+ btr &= ~0x40; -+ if (!(PCI_FUNC(pdev->devfn) & 1)) -+ btr |= 0x2; -+ else -+ btr |= (rev >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2; -+ pci_write_config_byte(pdev, 0x5A, btr); -+ -+ return btr; -+} -+ -+static void serverworks_fixup_ht1000(struct pci_dev *pdev) -+{ -+ u8 btr; -+ /* Setup HT1000 SouthBridge Controller - Single Channel Only */ -+ pci_read_config_byte(pdev, 0x5A, &btr); -+ btr &= ~0x40; -+ btr |= 0x3; -+ pci_write_config_byte(pdev, 0x5A, btr); -+} -+ -+ -+static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ int ports = 2; -+ static struct ata_port_info info[4] = { -+ { /* OSB4 */ -+ .sht = &serverworks_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x07, -+ .port_ops = &serverworks_osb4_port_ops -+ }, { /* OSB4 no UDMA */ -+ .sht = &serverworks_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x00, -+ .port_ops = &serverworks_osb4_port_ops -+ }, { /* CSB5 */ -+ .sht = &serverworks_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, -+ .port_ops = &serverworks_csb_port_ops -+ }, { /* CSB5 - later revisions*/ -+ .sht = &serverworks_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &serverworks_csb_port_ops -+ } -+ }; -+ static struct ata_port_info *port_info[2]; -+ struct ata_port_info *devinfo = &info[id->driver_data]; -+ -+ /* Force master latency timer to 64 PCI clocks */ -+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40); -+ -+ /* OSB4 : South Bridge and IDE */ -+ if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { -+ /* Select non UDMA capable OSB4 if we can't do fixups */ -+ if( serverworks_fixup_osb4(pdev) < 0) -+ devinfo = &info[1]; -+ } -+ /* setup CSB5/CSB6 : South Bridge and IDE option RAID */ -+ else if ((pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) || -+ (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || -+ (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) { -+ -+ /* If the returned btr is the newer revision then -+ select the right info block */ -+ if(serverworks_fixup_csb(pdev) == 3) -+ devinfo = &info[3]; -+ -+ /* Is this the 3rd channel CSB6 IDE ? */ -+ if(pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) -+ ports = 1; -+ } -+ /* setup HT1000E */ -+ else if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) -+ serverworks_fixup_ht1000(pdev); -+ -+ if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) -+ ata_pci_clear_simplex(pdev); -+ -+ port_info[0] = port_info[1] = devinfo; -+ return ata_pci_init_one(pdev, port_info, ports); -+} -+ -+static struct pci_device_id serverworks[] = { -+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { 0, }, -+}; -+ -+static struct pci_driver serverworks_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = serverworks, -+ .probe = serverworks_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init serverworks_init(void) -+{ -+ return pci_register_driver(&serverworks_pci_driver); -+} -+ -+ -+static void __exit serverworks_exit(void) -+{ -+ pci_unregister_driver(&serverworks_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Serverworks OSB4/CSB5/CSB6"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, serverworks); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(serverworks_init); -+module_exit(serverworks_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_sil680.c linux-2.6.16-rc2/drivers/scsi/pata_sil680.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_sil680.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_sil680.c 2006-01-21 17:04:00.000000000 +0000 -@@ -0,0 +1,362 @@ -+/* -+ * pata_sil680.c - SIL680 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon -+ * -+ * linux/drivers/ide/pci/siimage.c Version 1.07 Nov 30, 2003 -+ * -+ * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> -+ * Copyright (C) 2003 Red Hat <alan@redhat.com> -+ * -+ * May be copied or modified under the terms of the GNU General Public License -+ * -+ * Documentation publically available. -+ * -+ * If you have strange problems with nVidia chipset systems please -+ * see the SI support documentation and update your system BIOS -+ * if neccessary -+ * -+ * TODO -+ * If we know all our devices are LBA28 (or LBA28 sized) we could use -+ * the command fifo mode. -+ * Mode filters for shared PIO -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_sil680" -+#define DRV_VERSION "0.1" -+ -+/** -+ * sil680_selreg - return register base -+ * @hwif: interface -+ * @r: config offset -+ * -+ * Turn a config register offset into the right address in either -+ * PCI space or MMIO space to access the control register in question -+ * Thankfully this is a configuration operation so isnt performance -+ * criticial. -+ */ -+ -+static unsigned long sil680_selreg(struct ata_port *ap, int r) -+{ -+ unsigned long base = 0xA0 + r; -+ base += (ap->hard_port_no << 4); -+ return base; -+} -+ -+/** -+ * sil680_seldev - return register base -+ * @hwif: interface -+ * @r: config offset -+ * -+ * Turn a config register offset into the right address in either -+ * PCI space or MMIO space to access the control register in question -+ * including accounting for the unit shift. -+ */ -+ -+static unsigned long sil680_seldev(struct ata_port *ap, struct ata_device *adev, int r) -+{ -+ unsigned long base = 0xA0 + r; -+ base += (ap->hard_port_no << 4); -+ base |= adev->devno ? 2 : 0; -+ return base; -+} -+ -+ -+/** -+ * sil680_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection. The SIL680 stores this in PCI config -+ * space for us. -+ */ -+ -+static int sil680_cable_detect(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ unsigned long addr = sil680_selreg(ap, 0); -+ u8 ata66; -+ pci_read_config_byte(pdev, addr, &ata66); -+ if(ata66 & 1) -+ return ATA_CBL_PATA80; -+ else -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * sil680_bus_reset - reset the SIL680 bus -+ * @ap: ATA port to reset -+ * -+ * Perform the SIL680 housekeeping when doing an ATA bus reset -+ */ -+ -+static void sil680_bus_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ unsigned long addr = sil680_selreg(ap, 0); -+ u8 reset; -+ -+ pci_read_config_byte(pdev, addr, &reset); -+ pci_write_config_byte(pdev, addr, reset | 0x03); -+ udelay(25); -+ pci_write_config_byte(pdev, addr, reset); -+ ata_bus_reset(ap); -+} -+ -+static void sil680_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = sil680_cable_detect(ap); -+ sil680_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * sil680_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the SIL680 registers for PIO mode. Note that the task speed -+ * registers are shared between the devices so once the speed filters are -+ * in we must pick the lowest mode or switch. -+ */ -+ -+static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 }; -+ static u16 speed_t[5] = { 0x328A, 0x1281, 0x1281, 0x10C3, 0x10C1 }; -+ -+ unsigned long tfaddr = sil680_selreg(ap, 0x02); -+ unsigned long addr = sil680_seldev(ap, adev, 0x04); -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int pio = adev->pio_mode - XFER_PIO_0; -+ u16 reg; -+ -+ pci_write_config_word(pdev, addr, speed_p[pio]); -+ pci_write_config_word(pdev, tfaddr, speed_t[pio]); -+ -+ pci_read_config_word(pdev, tfaddr-2, ®); -+ reg &= ~0x0200; /* Clear IORDY */ -+ if(pio > 2) -+ reg |= 0x0200; /* Enable IORDY */ -+ pci_write_config_word(pdev, tfaddr-2, reg); -+} -+ -+/** -+ * sil680_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the MWDMA/UDMA modes for the sil680 k -+ * chipset. The MWDMA mode values are pulled from a lookup table -+ * while the chipset uses mode number for UDMA. We don't yet handle -+ * the shared pio speed stuff in full. FIXME -+ */ -+ -+static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u8 ultra_table[2][7] = { -+ { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01, 0xFF }, /* 100MHz */ -+ { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }, /* 133Mhz */ -+ }; -+ static u16 dma_table[3] = { 0x2208, 0x10C2, 0x10C1 }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ unsigned long ma = sil680_seldev(ap, adev, 0x08); -+ unsigned long ua = sil680_seldev(ap, adev, 0x0C); -+ unsigned long addr_mask = 0x80 + 4 * ap->hard_port_no; -+ int port_shift = adev->devno * 4; -+ u8 scsc, mode; -+ u16 multi, ultra; -+ -+ pci_read_config_byte(pdev, 0x8A, &scsc); -+ pci_read_config_byte(pdev, addr_mask, &mode); -+ pci_read_config_word(pdev, ma, &multi); -+ pci_read_config_word(pdev, ua, &ultra); -+ -+ /* Mask timing bits */ -+ ultra &= ~0x3F; -+ mode &= ~(0x03 << port_shift); -+ -+ /* Extract scsc */ -+ scsc = (scsc & 0x30) ? 1: 0; -+ -+ if(adev->dma_mode >= XFER_UDMA_0) { -+ multi = 0x10C1; -+ ultra |= ultra_table[scsc][adev->dma_mode - XFER_UDMA_0]; -+ mode |= (0x03 << port_shift); -+ } else { -+ multi = dma_table[adev->dma_mode - XFER_MW_DMA_0]; -+ mode |= (0x02 << port_shift); -+ } -+ pci_write_config_byte(pdev, addr_mask, mode); -+ pci_write_config_word(pdev, ma, multi); -+ pci_write_config_word(pdev, ua, ultra); -+} -+ -+static struct scsi_host_template sil680_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations sil680_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sil680_set_piomode, -+ .set_dmamode = sil680_set_dmamode, -+ .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 = sil680_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &sil680_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &sil680_port_ops -+ }; -+ static struct ata_port_info info_slow = { -+ .sht = &sil680_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &sil680_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = {&info, &info}; -+ static int printed_version; -+ u32 class_rev = 0; -+ u8 tmpbyte = 0; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); -+ -+ pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); -+ class_rev &= 0xff; -+ /* FIXME: double check */ -+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255); -+ -+ pci_write_config_byte(pdev, 0x80, 0x00); -+ pci_write_config_byte(pdev, 0x84, 0x00); -+ pci_read_config_byte(pdev, 0x8A, &tmpbyte); -+ switch(tmpbyte & 0x30) { -+ case 0x00: -+ /* 133 clock attempt to force it on */ -+ pci_write_config_byte(pdev, 0x8A, tmpbyte|0x10); -+ case 0x30: -+ /* if clocking is disabled */ -+ /* 133 clock attempt to force it on */ -+ pci_write_config_byte(pdev, 0x8A, tmpbyte & ~0x20); -+ case 0x10: -+ /* 133 already */ -+ break; -+ case 0x20: -+ /* BIOS set PCI x2 clocking */ -+ break; -+ } -+ -+ pci_read_config_byte(pdev, 0x8A, &tmpbyte); -+ if((tmpbyte & 0x30) == 0) -+ port_info[0] = port_info[1] = &info_slow; -+ -+ pci_write_config_byte(pdev, 0xA1, 0x72); -+ pci_write_config_word(pdev, 0xA2, 0x328A); -+ pci_write_config_dword(pdev, 0xA4, 0x62DD62DD); -+ pci_write_config_dword(pdev, 0xA8, 0x43924392); -+ pci_write_config_dword(pdev, 0xAC, 0x40094009); -+ pci_write_config_byte(pdev, 0xB1, 0x72); -+ pci_write_config_word(pdev, 0xB2, 0x328A); -+ pci_write_config_dword(pdev, 0xB4, 0x62DD62DD); -+ pci_write_config_dword(pdev, 0xB8, 0x43924392); -+ pci_write_config_dword(pdev, 0xBC, 0x40094009); -+ -+ switch(tmpbyte & 0x30) { -+ case 0x00: printk(KERN_INFO "sil680: 100MHz clock.\n");break; -+ case 0x10: printk(KERN_INFO "sil680: 133MHz clock.\n");break; -+ case 0x20: printk(KERN_INFO "sil680: Using PCI clock.\n");break; -+ /* This last case is _NOT_ ok */ -+ case 0x30: printk(KERN_ERR "sil680: Clock disabled ?\n"); -+ return -EIO; -+ } -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id sil680[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680), }, -+ { 0, }, -+}; -+ -+static struct pci_driver sil680_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = sil680, -+ .probe = sil680_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init sil680_init(void) -+{ -+ return pci_register_driver(&sil680_pci_driver); -+} -+ -+ -+static void __exit sil680_exit(void) -+{ -+ pci_unregister_driver(&sil680_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for SI680 PATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, sil680); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(sil680_init); -+module_exit(sil680_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_sis.c linux-2.6.16-rc2/drivers/scsi/pata_sis.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_sis.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_sis.c 2006-02-07 13:38:21.080709248 +0000 -@@ -0,0 +1,982 @@ -+/* -+ * pata_sis.c - SiS ATA driver -+ * -+ * (C) 2005 Red Hat <alan@redhat.com> -+ * -+ * Based upon linux/drivers/ide/pci/sis5513.c -+ * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> -+ * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer -+ * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz> -+ * SiS Taiwan : for direct support and hardware. -+ * Daniela Engert : for initial ATA100 advices and numerous others. -+ * John Fremlin, Manfred Spraul, Dave Morgan, Peter Kjellerstedt : -+ * for checking code correctness, providing patches. -+ * Original tests and design on the SiS620 chipset. -+ * ATA100 tests and design on the SiS735 chipset. -+ * ATA16/33 support from specs -+ * ATA133 support for SiS961/962 by L.C. Chang <lcchang@sis.com.tw> -+ * -+ * -+ * TODO -+ * Check MWDMA on drives that don't support MWDMA speed pio cycles ? -+ * More Testing -+ */ -+ -+#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/device.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/ata.h> -+ -+#define DRV_NAME "pata_sis" -+#define DRV_VERSION "0.1" -+ -+struct sis_chipset { -+ u16 device; /* PCI host ID */ -+ struct ata_port_info *info; /* Info block */ -+ /* Probably add family, cable detect type etc here to clean -+ up code later */ -+}; -+ -+/** -+ * sis_133_cable_detect - check for 40/80 pin -+ * @ap: Port -+ * -+ * Perform cable detection for the later UDMA133 capable -+ * SiS chipset. -+ */ -+ -+static int sis_133_cable_detect(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u16 tmp; -+ -+ pci_read_config_word(pdev, 0x50 + 2 * ap->hard_port_no, &tmp); -+ if(tmp & 0x8000) -+ return ATA_CBL_PATA40; -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * sis_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_133_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits sis_enable_bits[] = { -+ { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */ -+ { 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = sis_133_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+ -+/** -+ * sis_66_cable_detect - check for 40/80 pin -+ * @ap: Port -+ * -+ * Perform cable detection on the UDMA66, UDMA100 and early UDMA133 -+ * SiS IDE controllers. -+ */ -+ -+static int sis_66_cable_detect(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 tmp; -+ -+ pci_read_config_byte(pdev, 0x48, &tmp); -+ tmp >>= ap->hard_port_no; -+ if(tmp & 0x10) -+ return ATA_CBL_PATA40; -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * sis_66_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_66_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits sis_enable_bits[] = { -+ { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */ -+ { 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = sis_66_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+ -+/** -+ * sis_old_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_old_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits sis_enable_bits[] = { -+ { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */ -+ { 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * sis_set_fifo - Set RWP fifo bits for this device -+ * @ap: Port -+ * @adev: Device -+ * -+ * SIS chipsets implement prefetch/postwrite bits for each device -+ * on both channels. This functionality is not ATAPI compatible and -+ * must be configured according to the class of device present -+ */ -+ -+static void sis_set_fifo(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 reg4b; -+ u8 mask = 0x11; -+ -+ mask <<= (2 * ap->hard_port_no); -+ mask <<= adev->devno; -+ -+ pci_read_config_byte(pdev, 0x4B, ®4b); -+ reg4b &= ~mask; -+ -+ /* Enable for ATA (disk) only */ -+ if(adev->class == ATA_DEV_ATA) -+ reg4b |= mask; -+ pci_write_config_byte(pdev, 0x4B, reg4b); -+} -+ -+/** -+ * sis_old_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring for. -+ * -+ * Set PIO mode for device, in host controller PCI config space. This -+ * function handles PIO set up for all chips that are pre ATA100 and -+ * also early ATA100 devices. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int port = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ u8 t1, t2; -+ int speed = adev->pio_mode - XFER_PIO_0; -+ -+ const u8 active[] = { 0x00, 0x07, 0x04, 0x03, 0x01 }; -+ const u8 recovery[] = { 0x00, 0x06, 0x04, 0x03, 0x03 }; -+ -+ sis_set_fifo(ap, adev); -+ -+ pci_read_config_byte(pdev, port, &t1); -+ pci_read_config_byte(pdev, port + 1, &t2); -+ -+ t1 &= ~0x0F; /* Clear active/recovery timings */ -+ t2 &= ~0x07; -+ -+ t1 |= active[speed]; -+ t2 |= recovery[speed]; -+ -+ pci_write_config_byte(pdev, port, t1); -+ pci_write_config_byte(pdev, port + 1, t2); -+} -+ -+/** -+ * sis_100_set_pioode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring for. -+ * -+ * Set PIO mode for device, in host controller PCI config space. This -+ * function handles PIO set up for ATA100 devices and early ATA133. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_100_set_piomode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int port = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ int speed = adev->pio_mode - XFER_PIO_0; -+ -+ const u8 actrec[] = { 0x00, 0x67, 0x44, 0x33, 0x31 }; -+ -+ sis_set_fifo(ap, adev); -+ -+ pci_write_config_byte(pdev, port, actrec[speed]); -+} -+ -+/** -+ * sis_133_set_pioode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring for. -+ * -+ * Set PIO mode for device, in host controller PCI config space. This -+ * function handles PIO set up for the later ATA133 devices. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_133_set_piomode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int port = 0x40; -+ u32 t1; -+ u32 reg54; -+ int speed = adev->pio_mode - XFER_PIO_0; -+ -+ const u32 timing100[] = { -+ 0x28269000, /* Recovery << 24 | Act << 16 | Ini << 12 */ -+ 0x0C266000, -+ 0x04263000, -+ 0x0C0A3000, -+ 0x05093000 -+ }; -+ const u32 timing133[] = { -+ 0x1E1C6000, /* Recovery << 24 | Act << 16 | Ini << 12 */ -+ 0x091C4000, -+ 0x031C2000, -+ 0x09072000, -+ 0x04062000 -+ }; -+ -+ sis_set_fifo(ap, adev); -+ -+ pci_read_config_dword(pdev, 0x54, ®54); -+ if(reg54 & 0x40000000) -+ port = 0x70; -+ port += 8 * ap->hard_port_no + 4 * adev->devno; -+ -+ pci_read_config_dword(pdev, port, &t1); -+ t1 &= 0xC0C00FFF; /* Mask out timing */ -+ -+ if(t1 & 0x08) /* 100 or 133 ? */ -+ t1 |= timing133[speed]; -+ else -+ t1 |= timing100[speed]; -+ pci_write_config_byte(pdev, port, t1); -+} -+ -+/** -+ * sis_old_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * Handles pre UDMA and UDMA33 devices. Supports MWDMA as well unlike -+ * the old ide/pci driver. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_old_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ int drive_pci = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ u16 timing; -+ -+ const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 }; -+ const u16 udma_bits[] = { -+ 0xE000, 0xC000, 0xA000 -+ }; -+ -+ pci_read_config_word(pdev, drive_pci, &timing); -+ -+ if(adev->dma_mode < XFER_UDMA_0) { -+ /* bits 3-0 hold recovery timing bits 8-10 active timing and -+ the higer bits are dependant on the device */ -+ timing &= ~ 0x870F; -+ timing |= mwdma_bits[speed]; -+ pci_write_config_word(pdev, drive_pci, timing); -+ } else { -+ /* Bit 15 is UDMA on/off, bit 13-14 are cycle time */ -+ speed = adev->dma_mode - XFER_UDMA_0; -+ timing &= ~0x6000; -+ timing |= udma_bits[speed]; -+ } -+} -+ -+/** -+ * sis_66_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * Handles UDMA66 and early UDMA100 devices. Supports MWDMA as well unlike -+ * the old ide/pci driver. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ int drive_pci = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ u16 timing; -+ -+ const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 }; -+ const u16 udma_bits[] = { 0xF000, 0xD000, 0xB000, 0xA000, 0x9000}; -+ -+ pci_read_config_word(pdev, drive_pci, &timing); -+ -+ if(adev->dma_mode < XFER_UDMA_0) { -+ /* bits 3-0 hold recovery timing bits 8-10 active timing and -+ the higer bits are dependant on the device, bit 15 udma */ -+ timing &= ~ 0x870F; -+ timing |= mwdma_bits[speed]; -+ } else { -+ /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */ -+ speed = adev->dma_mode - XFER_UDMA_0; -+ timing &= ~0x6000; -+ timing |= udma_bits[speed]; -+ } -+ pci_write_config_word(pdev, drive_pci, timing); -+} -+ -+/** -+ * sis_100_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * Handles UDMA66 and early UDMA100 devices. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_100_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ int drive_pci = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ u16 timing; -+ -+ const u16 udma_bits[] = { 0x8B00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100}; -+ -+ pci_read_config_word(pdev, drive_pci, &timing); -+ -+ if(adev->dma_mode < XFER_UDMA_0) { -+ /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */ -+ } else { -+ /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */ -+ speed = adev->dma_mode - XFER_UDMA_0; -+ timing &= ~0x0F00; -+ timing |= udma_bits[speed]; -+ } -+ pci_write_config_word(pdev, drive_pci, timing); -+} -+ -+/** -+ * sis_133_early_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * Handles early SiS 961 bridges. Supports MWDMA as well unlike -+ * the old ide/pci driver. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ int drive_pci = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ u16 timing; -+ -+ const u16 udma_bits[] = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100}; -+ -+ pci_read_config_word(pdev, drive_pci, &timing); -+ -+ if(adev->dma_mode < XFER_UDMA_0) { -+ /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */ -+ } else { -+ /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */ -+ speed = adev->dma_mode - XFER_UDMA_0; -+ timing &= ~0x0F00; -+ timing |= udma_bits[speed]; -+ } -+ pci_write_config_word(pdev, drive_pci, timing); -+} -+ -+/** -+ * sis_133_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * Handles early SiS 961 bridges. Supports MWDMA as well unlike -+ * the old ide/pci driver. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_133_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ int port = 0x40; -+ u32 t1; -+ u32 reg54; -+ -+ /* bits 4- cycle time 8 - cvs time */ -+ const u32 timing_u100[] = { 0x6B0, 0x470, 0x350, 0x140, 0x120, 0x110, 0x000 }; -+ const u32 timing_u133[] = { 0x9F0, 0x6A0, 0x470, 0x250, 0x230, 0x220, 0x210 }; -+ -+ pci_read_config_dword(pdev, 0x54, ®54); -+ if(reg54 & 0x40000000) -+ port = 0x70; -+ port += 8 * ap->hard_port_no + 4 * adev->devno; -+ -+ pci_read_config_dword(pdev, port, &t1); -+ -+ if(adev->dma_mode < XFER_UDMA_0) { -+ t1 &= ~0x00000004; -+ /* FIXME: need data sheet to add MWDMA here. Also lacking on -+ ide/pci driver */ -+ } else { -+ speed = adev->dma_mode - XFER_UDMA_0; -+ /* if & 8 no UDMA133 - need info for ... */ -+ t1 &= ~0x00000FF0; -+ t1 |= 0x00000004; -+ if(t1 & 0x08) -+ t1 |= timing_u133[speed]; -+ else -+ t1 |= timing_u100[speed]; -+ } -+ pci_write_config_dword(pdev, port, t1); -+} -+ -+static struct 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, -+ .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, -+// .ordered_flush = 1, -+}; -+ -+static const struct ata_port_operations sis_133_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sis_133_set_piomode, -+ .set_dmamode = sis_133_set_dmamode, -+ -+ .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 = sis_133_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations sis_133_early_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sis_100_set_piomode, -+ .set_dmamode = sis_133_early_set_dmamode, -+ -+ .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 = sis_66_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations sis_100_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sis_100_set_piomode, -+ .set_dmamode = sis_100_set_dmamode, -+ -+ .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 = sis_66_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations sis_66_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sis_old_set_piomode, -+ .set_dmamode = sis_66_set_dmamode, -+ -+ .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 = sis_66_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations sis_old_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sis_old_set_piomode, -+ .set_dmamode = sis_old_set_dmamode, -+ -+ .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 = sis_old_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static struct ata_port_info sis_info = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, -+ .udma_mask = 0, -+ .port_ops = &sis_old_ops, -+}; -+static struct ata_port_info sis_info33 = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA2, /* UDMA 33 */ -+ .port_ops = &sis_old_ops, -+}; -+static struct ata_port_info sis_info66 = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .udma_mask = ATA_UDMA4, /* UDMA 66 */ -+ .port_ops = &sis_66_ops, -+}; -+static struct ata_port_info sis_info100 = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &sis_100_ops, -+}; -+static struct ata_port_info sis_info100_early = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .udma_mask = ATA_UDMA5, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .port_ops = &sis_66_ops, -+}; -+static struct ata_port_info sis_info133 = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .udma_mask = ATA_UDMA6, -+ .port_ops = &sis_133_ops, -+}; -+static struct ata_port_info sis_info133_early = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .udma_mask = ATA_UDMA6, -+ .port_ops = &sis_133_early_ops, -+}; -+ -+ -+static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis) -+{ -+ u16 regw; -+ u8 reg; -+ -+ if (sis->info == &sis_info133) { -+ pci_read_config_word(pdev, 0x50, ®w); -+ if(regw & 0x08) -+ pci_write_config_word(pdev, 0x50, regw & ~0x08); -+ pci_read_config_word(pdev, 0x52, ®w); -+ if(regw & 0x08) -+ pci_write_config_word(pdev, 0x52, regw & ~0x08); -+ return; -+ } -+ -+ if (sis->info == &sis_info133_early || sis->info == &sis_info100) { -+ /* Fix up latency */ -+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80); -+ /* Set compatibility bit */ -+ pci_read_config_byte(pdev, 0x49, ®); -+ if (!(reg & 0x01)) -+ pci_write_config_byte(pdev, 0x49, reg | 0x01); -+ return; -+ } -+ -+ if (sis->info == &sis_info66 || sis->info == &sis_info100_early) { -+ /* Fix up latency */ -+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80); -+ /* Set compatibility bit */ -+ pci_read_config_byte(pdev, 0x52, ®); -+ if (!(reg & 0x04)) -+ pci_write_config_byte(pdev, 0x52, reg | 0x04); -+ return; -+ } -+ -+ if (sis->info == &sis_info33) { -+ pci_read_config_byte(pdev, PCI_CLASS_PROG, ®); -+ if (( reg & 0x0F ) != 0x00) -+ pci_write_config_byte(pdev, PCI_CLASS_PROG, reg & 0xF0); -+ /* Fall through to ATA16 fixup below */ -+ } -+ -+ if (sis->info == &sis_info || sis->info == &sis_info33) { -+ /* force per drive recovery and active timings -+ needed on ATA_33 and below chips */ -+ pci_read_config_byte(pdev, 0x52, ®); -+ if (!(reg & 0x08)) -+ pci_write_config_byte(pdev, 0x52, reg|0x08); -+ return; -+ } -+ -+ BUG(); -+} -+ -+/** -+ * sis_init_one - Register SiS ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in sis_pci_tbl matching with @pdev -+ * -+ * Called from kernel PCI layer. We probe for combined mode (sigh), -+ * and then hand over control to libata, for it to do the rest. -+ * -+ * LOCKING: -+ * Inherited from PCI layer (may sleep). -+ * -+ * RETURNS: -+ * Zero on success, or -ERRNO value. -+ */ -+ -+static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ static struct ata_port_info *port_info[2]; -+ struct ata_port_info *port; -+ struct pci_dev *host; -+ struct sis_chipset *chipset = NULL; -+ -+ static struct sis_chipset sis_chipsets[] = { -+ { 0x0745, &sis_info100 }, -+ { 0x0735, &sis_info100 }, -+ { 0x0733, &sis_info100 }, -+ { 0x0635, &sis_info100 }, -+ { 0x0633, &sis_info100 }, -+ -+ { 0x0730, &sis_info100_early }, /* 100 with ATA 66 layout */ -+ { 0x0550, &sis_info100_early }, /* 100 with ATA 66 layout */ -+ -+ { 0x0640, &sis_info66 }, -+ { 0x0630, &sis_info66 }, -+ { 0x0620, &sis_info66 }, -+ { 0x0540, &sis_info66 }, -+ { 0x0530, &sis_info66 }, -+ -+ { 0x5600, &sis_info33 }, -+ { 0x5598, &sis_info33 }, -+ { 0x5597, &sis_info33 }, -+ { 0x5591, &sis_info33 }, -+ { 0x5582, &sis_info33 }, -+ { 0x5581, &sis_info33 }, -+ -+ { 0x5596, &sis_info }, -+ { 0x5571, &sis_info }, -+ { 0x5517, &sis_info }, -+ { 0x5511, &sis_info }, -+ -+ {0} -+ }; -+ static struct sis_chipset sis133_early = { -+ 0x0, &sis_info133_early -+ }; -+ static struct sis_chipset sis133 = { -+ 0x0, &sis_info133 -+ }; -+ static struct sis_chipset sis100_early = { -+ 0x0, &sis_info100_early -+ }; -+ static struct sis_chipset sis100 = { -+ 0x0, &sis_info100 -+ }; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, -+ "version " DRV_VERSION "\n"); -+ -+ /* We have to find the bridge first */ -+ -+ for (chipset = &sis_chipsets[0]; chipset->device; chipset++) { -+ host = pci_get_device(0x1039, chipset->device, NULL); -+ if (host != NULL) { -+ if (chipset->device == 0x630) { /* SIS630 */ -+ u8 host_rev; -+ pci_read_config_byte(host, PCI_REVISION_ID, &host_rev); -+ if(host_rev >= 0x30) /* 630 ET */ -+ chipset = &sis100_early; -+ } -+ break; -+ } -+ } -+ -+ /* Look for concealed bridges */ -+ if (host == NULL) { -+ /* Second check */ -+ u32 idemisc; -+ u16 trueid; -+ -+ /* Disable ID masking and register remapping then -+ see what the real ID is */ -+ -+ pci_read_config_dword(pdev, 0x54, &idemisc); -+ pci_write_config_dword(pdev, 0x54, idemisc & 0x7fffffff); -+ pci_read_config_word(pdev, PCI_DEVICE_ID, &trueid); -+ pci_write_config_dword(pdev, 0x54, idemisc); -+ -+ switch(trueid) { -+ case 0x5518: /* SIS 962/963 */ -+ chipset = &sis133; -+ if ((idemisc & 0x40000000) == 0) { -+ pci_write_config_dword(pdev, 0x54, idemisc | 0x40000000); -+ printk(KERN_INFO "SIS5513: Switching to 5513 register mapping\n"); -+ } -+ break; -+ case 0x0180: /* SIS 965/965L */ -+ chipset = &sis133; -+ break; -+ case 0x1180: /* SIS 966/966L */ -+ chipset = &sis133; -+ break; -+ } -+ } -+ -+ /* Further check */ -+ if(chipset == NULL) { -+ struct pci_dev *lpc_bridge; -+ u16 trueid; -+ u8 prefctl; -+ u8 idecfg; -+ u8 sbrev; -+ -+ /* Try the second unmasking technique */ -+ pci_read_config_byte(pdev, 0x4a, &idecfg); -+ pci_write_config_byte(pdev, 0x4a, idecfg | 0x10); -+ pci_read_config_word(pdev, PCI_DEVICE_ID, &trueid); -+ pci_write_config_byte(pdev, 0x4a, idecfg); -+ -+ switch(trueid) { -+ case 0x5517: -+ lpc_bridge = pci_get_slot(0x00, 0x10); /* Bus 0 Dev 2 Fn 0 */ -+ if(lpc_bridge == NULL) -+ break; -+ pci_read_config_byte(lpc_bridge, PCI_REVISION_ID, &sbrev); -+ pci_read_config_byte(pdev, 0x49, &prefctl); -+ pci_dev_put(lpc_bridge); -+ -+ if(sbrev == 0x10 && (prefctl & 0x80)) { -+ chipset = &sis133_early; -+ break; -+ } -+ chipset = &sis100; -+ break; -+ } -+ } -+ pci_dev_put(host); -+ -+ /* No chipset info, no support */ -+ if (chipset == NULL) -+ return -ENODEV; -+ -+ port = chipset->info; -+ port->private_data = chipset; -+ -+ sis_fixup(pdev, chipset); -+ -+ port_info[0] = port_info[1] = port; -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id sis_pci_tbl[] = { -+ { 0x1039, 0x5513, PCI_ANY_ID, PCI_ANY_ID, }, -+ { 0x1039, 0x5518, PCI_ANY_ID, PCI_ANY_ID, }, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver sis_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = sis_pci_tbl, -+ .probe = sis_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init sis_init(void) -+{ -+ return pci_register_driver(&sis_pci_driver); -+} -+ -+static void __exit sis_exit(void) -+{ -+ pci_unregister_driver(&sis_pci_driver); -+} -+ -+ -+module_init(sis_init); -+module_exit(sis_exit); -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("SCSI low-level driver for SiS ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, sis_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_sl82c105.c linux-2.6.16-rc2/drivers/scsi/pata_sl82c105.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_sl82c105.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_sl82c105.c 2006-01-21 17:05:02.000000000 +0000 -@@ -0,0 +1,376 @@ -+/* -+ * pata_sl82c105.c - SL82C105 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based in part on linux/drivers/ide/pci/sl82c105.c -+ * SL82C105/Winbond 553 IDE driver -+ * -+ * and in part on the documentation and errata sheet -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_sl82c105" -+#define DRV_VERSION "0.1.1" -+ -+enum { -+ /* -+ * SL82C105 PCI config register 0x40 bits. -+ */ -+ CTRL_IDE_IRQB = (1 << 30), -+ CTRL_IDE_IRQA = (1 << 28), -+ CTRL_LEGIRQ = (1 << 11), -+ CTRL_P1F16 = (1 << 5), -+ CTRL_P1EN = (1 << 4), -+ CTRL_P0F16 = (1 << 1), -+ CTRL_P0EN = (1 << 0) -+}; -+ -+static void sl82c105_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits sl82c105_enable_bits[] = { -+ { 0x40, 1, 0x01, 0x01 }, -+ { 0x40, 1, 0x10, 0x10 } -+ }; -+ -+ if (ap->hard_port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ dev_printk(KERN_INFO, &pdev->dev, "port disabled. ignoring.\n"); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+ -+/** -+ * sl82c105_configure_piomode - set chip PIO timing -+ * @ap: ATA interface -+ * @adev: ATA device -+ * @pio: PIO mode -+ * -+ * Called to do the PIO mode setup. Our timing registers are shared -+ * so a configure_dmamode call will undo any work we do here and vice -+ * versa -+ */ -+ -+static void sl82c105_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static u16 pio_timing[5] = { -+ 0x50D, 0x407, 0x304, 0x242, 0x240 -+ }; -+ u16 dummy; -+ int timing = 0x44 + 8 * ap->hard_port_no + 4 * adev->devno; -+ -+ pci_write_config_word(pdev, timing, pio_timing[pio]); -+ /* Can we lose this oddity of the old driver */ -+ pci_read_config_word(pdev, timing, &dummy); -+} -+ -+/** -+ * sl82c105_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. Our timing registers are shared -+ * but we want to set the PIO timing by default. -+ */ -+ -+static void sl82c105_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ sl82c105_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0); -+} -+ -+/** -+ * sl82c105_configure_dmamode - set DMA mode in chip -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Load DMA cycle times into the chip ready for a DMA transfer -+ * to occur. -+ */ -+ -+static void sl82c105_configure_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static u16 dma_timing[3] = { -+ 0x707, 0x201, 0x200 -+ }; -+ u16 dummy; -+ int timing = 0x44 + 8 * ap->hard_port_no + 4 * adev->devno; -+ int dma = adev->dma_mode - XFER_MW_DMA_0; -+ -+ pci_write_config_word(pdev, timing, dma_timing[dma]); -+ /* Can we lose this oddity of the old driver */ -+ pci_read_config_word(pdev, timing, &dummy); -+} -+ -+/** -+ * sl82c105_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the DMA mode setup. This replaces the PIO timings -+ * for the device in question. Set appropriate PIO timings not DMA -+ * timings at this point. -+ */ -+ -+static void sl82c105_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ switch(adev->dma_mode) { -+ case XFER_MW_DMA_0: -+ sl82c105_configure_piomode(ap, adev, 1); -+ break; -+ case XFER_MW_DMA_1: -+ sl82c105_configure_piomode(ap, adev, 3); -+ break; -+ case XFER_MW_DMA_2: -+ sl82c105_configure_piomode(ap, adev, 3); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+/** -+ * sl82c105_reset_engine - Reset the DMA engine -+ * @ap: ATA interface -+ * -+ * The sl82c105 has some serious problems with the DMA engine -+ * when transfers don't run as expected or ATAPI is used. The -+ * recommended fix is to reset the engine each use using a chip -+ * test register. -+ */ -+ -+static void sl82c105_reset_engine(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u16 val; -+ -+ pci_read_config_word(pdev, 0x7E, &val); -+ pci_write_config_word(pdev, 0x7E, val | 4); -+ pci_write_config_word(pdev, 0x7E, val & ~4); -+} -+ -+/** -+ * sl82c105_bmdma_start - DMA engine begin -+ * @qc: ATA command -+ * -+ * Reset the DMA engine each use as recommended by the errata -+ * document. -+ * -+ * FIXME: if we switch clock at BMDMA start/end we might get better -+ * PIO performance on DMA capable devices. -+ */ -+ -+static void sl82c105_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ -+ sl82c105_reset_engine(ap); -+ -+ /* Set the clocks for DMA */ -+ sl82c105_configure_dmamode(ap, qc->dev); -+ /* Activate DMA */ -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * sl82c105_bmdma_end - DMA engine stop -+ * @qc: ATA command -+ * -+ * Reset the DMA engine each use as recommended by the errata -+ * document. -+ * -+ * This function is also called to turn off DMA when a timeout occurs -+ * during DMA operation. In both cases we need to reset the engine, -+ * so no actual eng_timeout handler is required. -+ * -+ * We assume bmdma_stop is always called if bmdma_start as called. If -+ * not then we may need to wrap qc_issue. -+ */ -+ -+static void sl82c105_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ -+ ata_bmdma_stop(qc); -+ sl82c105_reset_engine(ap); -+ -+ /* This will redo the initial setup of the DMA device to matching -+ PIO timings */ -+ sl82c105_set_dmamode(ap, qc->dev); -+} -+ -+static struct scsi_host_template sl82c105_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations sl82c105_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sl82c105_set_piomode, -+ .set_dmamode = sl82c105_set_dmamode, -+ .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 = sl82c105_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = sl82c105_bmdma_start, -+ .bmdma_stop = sl82c105_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * sl82c105_bridge_revision - find bridge version -+ * @pdev: PCI device for the ATA function -+ * -+ * Locates the PCI bridge associated with the ATA function and -+ * providing it is a Winbond 553 reports the revision. If it cannot -+ * find a revision or the right device it returns -1 -+ */ -+ -+static int sl82c105_bridge_revision(struct pci_dev *pdev) -+{ -+ struct pci_dev *bridge; -+ u8 rev; -+ -+ /* -+ * The bridge should be part of the same device, but function 0. -+ */ -+ bridge = pci_get_slot(pdev->bus, -+ PCI_DEVFN(PCI_SLOT(pdev->devfn), 0)); -+ if (!bridge) -+ return -1; -+ -+ /* -+ * Make sure it is a Winbond 553 and is an ISA bridge. -+ */ -+ if (bridge->vendor != PCI_VENDOR_ID_WINBOND || -+ bridge->device != PCI_DEVICE_ID_WINBOND_83C553 || -+ bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) { -+ pci_dev_put(bridge); -+ return -1; -+ } -+ /* -+ * We need to find function 0's revision, not function 1 -+ */ -+ pci_read_config_byte(bridge, PCI_REVISION_ID, &rev); -+ -+ pci_dev_put(bridge); -+ return rev; -+} -+ -+ -+static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info_dma = { -+ .sht = &sl82c105_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &sl82c105_port_ops -+ }; -+ static struct ata_port_info info_early = { -+ .sht = &sl82c105_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .port_ops = &sl82c105_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info_early, &info_early }; -+ u32 val; -+ int rev; -+ -+ rev = sl82c105_bridge_revision(dev); -+ -+ if(rev == -1) -+ dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Unable to find bridge, disabling DMA.\n"); -+ else if (rev <= 5) -+ dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Early bridge revision, no DMA available.\n"); -+ else { -+ port_info[0] = &info_dma; -+ port_info[1] = &info_dma; -+ } -+ -+ pci_read_config_dword(dev, 0x40, &val); -+ val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; -+ pci_write_config_dword(dev, 0x40, val); -+ -+ -+ return ata_pci_init_one(dev, port_info, 1); /* For now */ -+} -+ -+static struct pci_device_id sl82c105[] = { -+ { PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0, }, -+}; -+ -+static struct pci_driver sl82c105_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = sl82c105, -+ .probe = sl82c105_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init sl82c105_init(void) -+{ -+ return pci_register_driver(&sl82c105_pci_driver); -+} -+ -+ -+static void __exit sl82c105_exit(void) -+{ -+ pci_unregister_driver(&sl82c105_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Sl82c105"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, sl82c105); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(sl82c105_init); -+module_exit(sl82c105_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_triflex.c linux-2.6.16-rc2/drivers/scsi/pata_triflex.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_triflex.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_triflex.c 2006-01-21 17:05:13.000000000 +0000 -@@ -0,0 +1,268 @@ -+/* -+ * pata_triflex.c - Compaq PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon -+ * -+ * triflex.c -+ * -+ * IDE Chipset driver for the Compaq TriFlex IDE controller. -+ * -+ * Known to work with the Compaq Workstation 5x00 series. -+ * -+ * Copyright (C) 2002 Hewlett-Packard Development Group, L.P. -+ * Author: Torben Mathiasen <torben.mathiasen@hp.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Loosely based on the piix & svwks drivers. -+ * -+ * Documentation: -+ * Not publically available. -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_triflex" -+#define DRV_VERSION "0.2.1" -+ -+static void triflex_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits triflex_enable_bits[] = { -+ { 0x80, 1, 0x01, 0x01 }, -+ { 0x80, 1, 0x02, 0x02 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * triflex_load_timing - timing configuration -+ * @ap: ATA interface -+ * @adev: Device on the bus -+ * @speed: speed to configure -+ * -+ * The Triflex has one set of timings per device per channel. This -+ * means we must do some switching. As the PIO and DMA timings don't -+ * match we have to do some reloading unlike PIIX devices where tuning -+ * tricks can avoid it. -+ */ -+ -+static void triflex_load_timing(struct ata_port *ap, struct ata_device *adev, int speed) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 timing = 0; -+ u32 triflex_timing, old_triflex_timing; -+ int channel_offset = ap->hard_port_no ? 0x74: 0x70; -+ unsigned int is_slave = (adev->devno != 0); -+ -+ -+ pci_read_config_dword(pdev, channel_offset, &old_triflex_timing); -+ triflex_timing = old_triflex_timing; -+ -+ switch(speed) -+ { -+ case XFER_MW_DMA_2: -+ timing = 0x0103;break; -+ case XFER_MW_DMA_1: -+ timing = 0x0203;break; -+ case XFER_MW_DMA_0: -+ timing = 0x0808;break; -+ case XFER_SW_DMA_2: -+ case XFER_SW_DMA_1: -+ case XFER_SW_DMA_0: -+ timing = 0x0F0F;break; -+ case XFER_PIO_4: -+ timing = 0x0202;break; -+ case XFER_PIO_3: -+ timing = 0x0204;break; -+ case XFER_PIO_2: -+ timing = 0x0404;break; -+ case XFER_PIO_1: -+ timing = 0x0508;break; -+ case XFER_PIO_0: -+ timing = 0x0808;break; -+ default: -+ BUG(); -+ } -+ triflex_timing &= ~ (0xFFFF << (16 * is_slave)); -+ triflex_timing |= (timing << (16 * is_slave)); -+ -+ if(triflex_timing != old_triflex_timing) -+ pci_write_config_dword(pdev, channel_offset, triflex_timing); -+} -+ -+/** -+ * triflex_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Use the timing loader to set up the PIO mode. We have to do this -+ * because DMA start/stop will only be called once DMA occurs. If there -+ * has been no DMA then the PIO timings are still needed. -+ */ -+static void triflex_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ triflex_load_timing(ap, adev, adev->pio_mode); -+} -+ -+/** -+ * triflex_dma_start - DMA start callback -+ * @qc: Command in progress -+ * -+ * Usually drivers set the DMA timing at the point the set_dmamode call -+ * is made. Triflex however requires we load new timings on the -+ * transition or keep matching PIO/DMA pairs (ie MWDMA2/PIO4 etc). -+ * We load the DMA timings just before starting DMA and then restore -+ * the PIO timing when the DMA is finished. -+ */ -+ -+static void triflex_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ triflex_load_timing(qc->ap, qc->dev, qc->dev->dma_mode); -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * triflex_dma_stop - DMA stop callback -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * We loaded new timings in dma_start, as a result we need to restore -+ * the PIO timings in dma_stop so that the next command issue gets the -+ * right clock values. -+ */ -+ -+static void triflex_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ ata_bmdma_stop(qc); -+ triflex_load_timing(qc->ap, qc->dev, qc->dev->pio_mode); -+} -+ -+static struct scsi_host_template triflex_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations triflex_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = triflex_set_piomode, -+ .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 = triflex_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = triflex_bmdma_start, -+ .bmdma_stop = triflex_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &triflex_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &triflex_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ static int printed_version; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); -+ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static const struct pci_device_id triflex[] = { -+ { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, -+ { 0, }, -+}; -+ -+static struct pci_driver triflex_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = triflex, -+ .probe = triflex_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init triflex_init(void) -+{ -+ return pci_register_driver(&triflex_pci_driver); -+} -+ -+ -+static void __exit triflex_exit(void) -+{ -+ pci_unregister_driver(&triflex_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Compaq Triflex"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, triflex); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(triflex_init); -+module_exit(triflex_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/pata_via.c linux-2.6.16-rc2/drivers/scsi/pata_via.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/pata_via.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc2/drivers/scsi/pata_via.c 2006-01-21 17:06:09.000000000 +0000 -@@ -0,0 +1,547 @@ -+/* -+ * pata_via.c - VIA PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Documentation -+ * Most chipset documentation available under NDA only -+ * -+ * VIA version guide -+ * VIA VT82C561 - early design, uses ata_generic currently -+ * VIA VT82C576 - MWDMA, 33Mhz -+ * VIA VT82C586 - MWDMA, 33Mhz -+ * VIA VT82C586a - Added UDMA to 33Mhz -+ * VIA VT82C586b - UDMA33 -+ * VIA VT82C596a - Nonfunctional UDMA66 -+ * VIA VT82C596b - Working UDMA66 -+ * VIA VT82C686 - Nonfunctional UDMA66 -+ * VIA VT82C686a - Working UDMA66 -+ * VIA VT82C686b - Updated to UDMA100 -+ * VIA VT8231 - UDMA100 -+ * VIA VT8233 - UDMA100 -+ * VIA VT8233a - UDMA133 -+ * VIA VT8233c - UDMA100 -+ * VIA VT8235 - UDMA133 -+ * VIA VT8237 - UDMA133 -+ * -+ * Most registers remain compatible across chips. Others start reserved -+ * and acquire sensible semantics if set to 1 (eg cable detect). A few -+ * exceptions exist, notably around the FIFO settings. -+ * -+ * One additional quirk of the VIA design is that like ALi they use few -+ * PCI IDs for a lot of chips. -+ * -+ * Based heavily on: -+ * -+ * Version 3.38 -+ * -+ * VIA IDE driver for Linux. Supported southbridges: -+ * -+ * vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b, -+ * vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a, -+ * vt8235, vt8237 -+ * -+ * Copyright (c) 2000-2002 Vojtech Pavlik -+ * -+ * Based on the work of: -+ * Michel Aubry -+ * Jeff Garzik -+ * Andre Hedrick -+ -+ */ -+ -+#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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_via" -+#define DRV_VERSION "0.1.3" -+ -+/* -+ * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx -+ * driver. -+ */ -+ -+enum { -+ VIA_UDMA = 0x007, -+ VIA_UDMA_NONE = 0x000, -+ VIA_UDMA_33 = 0x001, -+ VIA_UDMA_66 = 0x002, -+ VIA_UDMA_100 = 0x003, -+ VIA_UDMA_133 = 0x004, -+ VIA_BAD_PREQ = 0x010, /* Crashes if PREQ# till DDACK# set */ -+ VIA_BAD_CLK66 = 0x020, /* 66 MHz clock doesn't work correctly */ -+ VIA_SET_FIFO = 0x040, /* Needs to have FIFO split set */ -+ VIA_NO_UNMASK = 0x080, /* Doesn't work with IRQ unmasking on */ -+ VIA_BAD_ID = 0x100, /* Has wrong vendor ID (0x1107) */ -+ VIA_BAD_AST = 0x200, /* Don't touch Address Setup Timing */ -+}; -+ -+/* -+ * VIA SouthBridge chips. -+ */ -+ -+static const struct via_isa_bridge { -+ const char *name; -+ u16 id; -+ u8 rev_min; -+ u8 rev_max; -+ u16 flags; -+} via_isa_bridges[] = { -+ { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, -+ { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, -+ { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, -+ { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, VIA_UDMA_100 }, -+ { "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, VIA_UDMA_100 }, -+ { "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, VIA_UDMA_100 }, -+ { "vt82c686b", PCI_DEVICE_ID_VIA_82C686, 0x40, 0x4f, VIA_UDMA_100 }, -+ { "vt82c686a", PCI_DEVICE_ID_VIA_82C686, 0x10, 0x2f, VIA_UDMA_66 }, -+ { "vt82c686", PCI_DEVICE_ID_VIA_82C686, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, -+ { "vt82c596b", PCI_DEVICE_ID_VIA_82C596, 0x10, 0x2f, VIA_UDMA_66 }, -+ { "vt82c596a", PCI_DEVICE_ID_VIA_82C596, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, -+ { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO }, -+ { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ }, -+ { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO }, -+ { "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO }, -+ { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO }, -+ { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK }, -+ { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, -+ { NULL } -+}; -+ -+/** -+ * via_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection. Actually for the VIA case the BIOS -+ * already did this for us. We read the values provided by the -+ * BIOS. If you are using an 8235 in a non-PC configuration you -+ * may need to update this code. -+ * -+ * Hotplug also impacts on this. -+ */ -+ -+static int via_cable_detect(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 ata66; -+ pci_read_config_dword(pdev, 0x50, &ata66); -+ /* Check both the drive cable reporting bits, we might not have -+ two drives */ -+ if(ata66 & (0x1010 << (16 * ap->hard_port_no))) -+ return ATA_CBL_PATA80; -+ else -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * via_phy_reset - reset for eary chip -+ * @ap: ATA port -+ * -+ * Handle the reset callback for the later chips with cable detect -+ */ -+ -+static void via_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ /* Note: When we add VIA 6410 remember it doesn't have enable bits */ -+ static struct pci_bits via_enable_bits[] = { -+ { 0x40, 1, 0x02, 0x02 }, -+ { 0x40, 1, 0x01, 0x01 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &via_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = via_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * via_do_set_mode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * @mode: ATA mode being programmed -+ * @tdiv: Clocks per PCI clock -+ * @set_ast: Set to program address setup -+ * @udma_type: UDMA mode/format of registers -+ * -+ * Program the VIA registers for DMA and PIO modes. Uses the ata timing -+ * support in order to compute modes. -+ * -+ * FIXME: Hotplug will require we serialize multiple mode changes -+ * on the two channels. -+ */ -+ -+static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mode, int tdiv, int set_ast, int udma_type) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct ata_device *peer = &ap->device[1 - adev->devno]; -+ struct ata_timing t, p; -+ static int via_clock = 33000; /* Bus clock in kHZ - ought to be tunable one day */ -+ unsigned long T = 1000000000 / via_clock; -+ unsigned long UT = T/tdiv; -+ int ut; -+ int offset = 3 - (2*ap->hard_port_no) - adev->devno; -+ -+ printk("via_do_set_mode: Mode=%d ast broken=%c udma=%d mul=%d\n", -+ mode, "YN"[set_ast], udma_type, tdiv); -+ /* Calculate the timing values we require */ -+ ata_timing_compute(adev, adev->pio_mode, &t, T, UT); -+ -+ /* We share 8bit timing so we must merge the constraints */ -+ if(ata_dev_present(peer)) { -+ if(peer->pio_mode) { -+ ata_timing_compute(peer, peer->pio_mode, &p, T, UT); -+ ata_timing_merge(&p, &t, &t, ATA_TIMING_8BIT); -+ } -+ if(peer->dma_mode) { -+ ata_timing_compute(peer, peer->dma_mode, &p, T, UT); -+ ata_timing_merge(&p, &t, &t, ATA_TIMING_8BIT); -+ } -+ } -+ -+ /* Address setup is programmable but breaks on UDMA133 setups */ -+ if(set_ast) { -+ u8 setup; /* 2 bits per drive */ -+ int shift = 2 * offset; -+ -+ pci_read_config_byte(pdev, 0x4C, &setup); -+ setup &= ~(3 << shift); -+ setup |= FIT(t.setup, 1, 4) << shift; -+ pci_write_config_byte(pdev, 0x4C, setup); -+ } -+ -+ /* Load the PIO mode bits */ -+ pci_write_config_byte(pdev, 0x4F - ap->hard_port_no, -+ ((FIT(t.act8b, 1, 16) - 1) << 4) | (FIT(t.rec8b, 1, 16) - 1)); -+ pci_write_config_byte(pdev, 0x48 + offset, -+ ((FIT(t.active, 1, 16) - 1) << 4) | (FIT(t.recover, 1, 16) - 1)); -+ -+ /* Load the UDMA bits according to type */ -+ switch(udma_type) { -+ default: -+ /* BUG() ? */ -+ /* fall through */ -+ case 33: -+ ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 5) - 2)) : 0x03; -+ break; -+ case 66: -+ ut = t.udma ? (0xe8 | (FIT(t.udma, 2, 9) - 2)) : 0x0f; -+ break; -+ case 100: -+ ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07; -+ break; -+ case 133: -+ ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07; -+ break; -+ } -+ /* Set UDMA unless device is not UDMA capable */ -+ if(udma_type) -+ pci_write_config_byte(pdev, 0x50 + offset, ut); -+} -+ -+static void via_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ const struct via_isa_bridge *config = ap->host_set->private_data; -+ int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1; -+ int mode = config->flags & VIA_UDMA; -+ static u8 tclock[5] = { 1, 1, 2, 3, 4 }; -+ static u8 udma[5] = { 0, 33, 66, 100, 133 }; -+ -+ via_do_set_mode(ap, adev, adev->pio_mode, tclock[mode], set_ast, udma[mode]); -+} -+ -+static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ const struct via_isa_bridge *config = ap->host_set->private_data; -+ int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1; -+ int mode = config->flags & VIA_UDMA; -+ static u8 tclock[5] = { 1, 1, 2, 3, 4 }; -+ static u8 udma[5] = { 0, 33, 66, 100, 133 }; -+ -+ via_do_set_mode(ap, adev, adev->dma_mode, tclock[mode], set_ast, udma[mode]); -+} -+ -+static struct scsi_host_template via_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, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations via_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = via_set_piomode, -+ .set_dmamode = via_set_dmamode, -+ .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 = via_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations via_port_ops_noirq = { -+ .port_disable = ata_port_disable, -+ .set_piomode = via_set_piomode, -+ .set_dmamode = via_set_dmamode, -+ .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 = via_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer_noirq, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * via_init_one - discovery callback -+ * @pdev: PCI device ID -+ * @id: PCI table info -+ * -+ * A VIA IDE interface has been discovered. Figure out what revision -+ * and perform configuration work before handing it to the ATA layer -+ */ -+ -+static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ /* Early VIA without UDMA support */ -+ static struct ata_port_info via_mwdma_info = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &via_port_ops -+ }; -+ /* Ditto with IRQ masking required */ -+ static struct ata_port_info via_mwdma_info_borked = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_IRQ_MASK, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &via_port_ops_noirq, -+ }; -+ /* VIA UDMA 33 devices (and borked 66) */ -+ static struct ata_port_info via_udma33_info = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7, -+ .port_ops = &via_port_ops -+ }; -+ /* VIA UDMA 66 devices */ -+ static struct ata_port_info via_udma66_info = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, -+ .port_ops = &via_port_ops -+ }; -+ /* VIA UDMA 100 devices */ -+ static struct ata_port_info via_udma100_info = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &via_port_ops -+ }; -+ /* UDMA133 with bad AST (All current 133) */ -+ static struct ata_port_info via_udma133_info = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* 0x7F but need to fix north bridge */ -+ .port_ops = &via_port_ops -+ }; -+ struct ata_port_info *port_info[2], *type; -+ struct pci_dev *isa = NULL; -+ const struct via_isa_bridge *config; -+ static int printed_version; -+ u8 t; -+ u8 enable; -+ u32 timing; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); -+ -+ /* To find out how the IDE will behave and what features we -+ actually have to look at the bridge not the IDE controller */ -+ for (config = via_isa_bridges; config->id; config++) -+ if ((isa = pci_get_device(PCI_VENDOR_ID_VIA + -+ !!(config->flags & VIA_BAD_ID), -+ config->id, NULL))) { -+ -+ pci_read_config_byte(isa, PCI_REVISION_ID, &t); -+ if (t >= config->rev_min && -+ t <= config->rev_max) -+ break; -+ pci_dev_put(isa); -+ } -+ -+ if (!config->id) { -+ printk(KERN_WARNING "via: Unknown VIA SouthBridge, disabling.\n"); -+ return -ENODEV; -+ } -+ -+ /* 0x40 low bits indicate enabled channels */ -+ pci_read_config_byte(pdev, 0x40 , &enable); -+ enable &= 3; -+ if(enable == 0) { -+ pci_dev_put(isa); -+ return -ENODEV; -+ } -+ -+ /* Initialise the FIFO for the enabled channels. */ -+ if (config->flags & VIA_SET_FIFO) { -+ u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20}; -+ u8 fifo; -+ -+ pci_read_config_byte(pdev, 0x43, &fifo); -+ -+ /* Clear PREQ# until DDACK# for errata */ -+ if(config->flags & VIA_BAD_PREQ) -+ fifo &= 0x7F; -+ else -+ fifo &= 0x9f; -+ /* Turn on FIFO for enabled channels */ -+ fifo |= fifo_setting[enable]; -+ pci_write_config_byte(pdev, 0x43, fifo); -+ } -+ /* Clock set up */ -+ switch(config->flags & VIA_UDMA) { -+ case VIA_UDMA_NONE: -+ if(config->flags & VIA_NO_UNMASK) -+ type = &via_mwdma_info_borked; -+ else -+ type = &via_mwdma_info; -+ break; -+ case VIA_UDMA_33: -+ type = &via_udma33_info; -+ break; -+ case VIA_UDMA_66: -+ type = &via_udma66_info; -+ /* The 66 MHz devices require we enable the clock */ -+ pci_read_config_dword(pdev, 0x50, &timing); -+ timing |= 0x80008; -+ pci_write_config_dword(pdev, 0x50, timing); -+ break; -+ case VIA_UDMA_100: -+ type = &via_udma100_info; -+ break; -+ case VIA_UDMA_133: -+ type = &via_udma133_info; -+ break; -+ default: -+ type = NULL; -+ BUG(); -+ break; -+ } -+ -+ if(config->flags & VIA_BAD_CLK66) { -+ /* Disable the 66MHz clock on problem devices */ -+ pci_read_config_dword(pdev, 0x50, &timing); -+ timing &= ~0x80008; -+ pci_write_config_dword(pdev, 0x50, timing); -+ } -+ -+ /* We have established the device type, now fire it up */ -+ type->private_data = (void *)config; -+ -+ port_info[0] = port_info[1] = type; -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id via[] = { -+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0, }, -+}; -+ -+static struct pci_driver via_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = via, -+ .probe = via_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init via_init(void) -+{ -+ return pci_register_driver(&via_pci_driver); -+} -+ -+ -+static void __exit via_exit(void) -+{ -+ pci_unregister_driver(&via_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for VIA PATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, via); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(via_init); -+module_exit(via_exit); -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_mv.c linux-2.6.16-rc2/drivers/scsi/sata_mv.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_mv.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_mv.c 2006-01-21 17:07:20.000000000 +0000 -@@ -389,6 +389,7 @@ - - .qc_prep = mv_qc_prep, - .qc_issue = mv_qc_issue, -+ .data_xfer = ata_mmio_data_xfer, - - .eng_timeout = mv_eng_timeout, - -@@ -416,6 +417,7 @@ - - .qc_prep = mv_qc_prep, - .qc_issue = mv_qc_issue, -+ .data_xfer = ata_mmio_data_xfer, - - .eng_timeout = mv_eng_timeout, - -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_nv.c linux-2.6.16-rc2/drivers/scsi/sata_nv.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_nv.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_nv.c 2006-01-21 17:08:58.000000000 +0000 -@@ -258,6 +258,7 @@ - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, - .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, - .irq_handler = nv_interrupt, - .irq_clear = ata_bmdma_irq_clear, - .scr_read = nv_scr_read, -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_promise.c linux-2.6.16-rc2/drivers/scsi/sata_promise.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_promise.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_promise.c 2006-02-06 12:36:12.000000000 +0000 -@@ -130,6 +130,7 @@ - .qc_prep = pdc_qc_prep, - .qc_issue = pdc_qc_issue_prot, - .eng_timeout = pdc_eng_timeout, -+ .data_xfer = ata_mmio_data_xfer, - .irq_handler = pdc_interrupt, - .irq_clear = pdc_irq_clear, - -@@ -152,6 +153,7 @@ - - .qc_prep = pdc_qc_prep, - .qc_issue = pdc_qc_issue_prot, -+ .data_xfer = ata_mmio_data_xfer, - .eng_timeout = pdc_eng_timeout, - .irq_handler = pdc_interrupt, - .irq_clear = pdc_irq_clear, -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_qstor.c linux-2.6.16-rc2/drivers/scsi/sata_qstor.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_qstor.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_qstor.c 2006-01-21 17:09:57.000000000 +0000 -@@ -158,6 +158,7 @@ - .phy_reset = qs_phy_reset, - .qc_prep = qs_qc_prep, - .qc_issue = qs_qc_issue, -+ .data_xfer = ata_mmio_data_xfer, - .eng_timeout = qs_eng_timeout, - .irq_handler = qs_intr, - .irq_clear = qs_irq_clear, -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_sil24.c linux-2.6.16-rc2/drivers/scsi/sata_sil24.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_sil24.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_sil24.c 2006-01-21 17:10:52.000000000 +0000 -@@ -309,6 +309,7 @@ - - .qc_prep = sil24_qc_prep, - .qc_issue = sil24_qc_issue, -+ .data_xfer = ata_mmio_data_xfer, - - .eng_timeout = sil24_eng_timeout, - -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_sil.c linux-2.6.16-rc2/drivers/scsi/sata_sil.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_sil.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_sil.c 2006-01-21 17:11:06.000000000 +0000 -@@ -165,6 +165,7 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_mmio_data_xfer, - .eng_timeout = ata_eng_timeout, - .irq_handler = ata_interrupt, - .irq_clear = ata_bmdma_irq_clear, -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_sis.c linux-2.6.16-rc2/drivers/scsi/sata_sis.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_sis.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_sis.c 2006-01-21 17:11:23.000000000 +0000 -@@ -115,6 +115,7 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, - .eng_timeout = ata_eng_timeout, - .irq_handler = ata_interrupt, - .irq_clear = ata_bmdma_irq_clear, -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_svw.c linux-2.6.16-rc2/drivers/scsi/sata_svw.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_svw.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_svw.c 2006-02-06 12:30:23.000000000 +0000 -@@ -320,6 +320,7 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_mmio_data_xfer, - .eng_timeout = ata_eng_timeout, - .irq_handler = ata_interrupt, - .irq_clear = ata_bmdma_irq_clear, -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_sx4.c linux-2.6.16-rc2/drivers/scsi/sata_sx4.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_sx4.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_sx4.c 2006-01-21 17:12:01.000000000 +0000 -@@ -206,6 +206,7 @@ - .phy_reset = pdc_20621_phy_reset, - .qc_prep = pdc20621_qc_prep, - .qc_issue = pdc20621_qc_issue_prot, -+ .data_xfer = ata_mmio_data_xfer, - .eng_timeout = pdc_eng_timeout, - .irq_handler = pdc20621_interrupt, - .irq_clear = pdc20621_irq_clear, -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_uli.c linux-2.6.16-rc2/drivers/scsi/sata_uli.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_uli.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_uli.c 2006-01-21 17:12:24.000000000 +0000 -@@ -106,6 +106,7 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, - - .eng_timeout = ata_eng_timeout, - -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_via.c linux-2.6.16-rc2/drivers/scsi/sata_via.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_via.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_via.c 2006-01-21 17:12:51.000000000 +0000 -@@ -126,6 +126,7 @@ - - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, - - .eng_timeout = ata_eng_timeout, - -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/drivers/scsi/sata_vsc.c linux-2.6.16-rc2/drivers/scsi/sata_vsc.c ---- linux.vanilla-2.6.16-rc2/drivers/scsi/sata_vsc.c 2006-02-06 12:21:40.000000000 +0000 -+++ linux-2.6.16-rc2/drivers/scsi/sata_vsc.c 2006-01-21 17:13:14.000000000 +0000 -@@ -252,6 +252,7 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, - .eng_timeout = ata_eng_timeout, - .irq_handler = vsc_sata_interrupt, - .irq_clear = ata_bmdma_irq_clear, -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/include/linux/ata.h linux-2.6.16-rc2/include/linux/ata.h ---- linux.vanilla-2.6.16-rc2/include/linux/ata.h 2006-02-06 12:21:42.000000000 +0000 -+++ linux-2.6.16-rc2/include/linux/ata.h 2006-02-07 11:30:07.000000000 +0000 -@@ -134,6 +134,8 @@ - ATA_CMD_PIO_READ_EXT = 0x24, - ATA_CMD_PIO_WRITE = 0x30, - ATA_CMD_PIO_WRITE_EXT = 0x34, -+ ATA_CMD_READ_NATIVE_MAX = 0xF8, -+ ATA_CMD_READ_NATIVE_MAX_EXT = 0x27, - ATA_CMD_READ_MULTI = 0xC4, - ATA_CMD_READ_MULTI_EXT = 0x29, - ATA_CMD_WRITE_MULTI = 0xC5, -@@ -247,13 +249,16 @@ - }; - - #define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0) -+#define ata_id_is_cfa(id) ((id)[0] == 0x848A) - #define ata_id_is_sata(id) ((id)[93] == 0) - #define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6)) - #define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5)) -+#define ata_id_hpa_enabled(id) ((id)[85] & (1 << 10)) - #define ata_id_has_fua(id) ((id)[84] & (1 << 6)) - #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_hpa(id) ((id)[82] & (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)) -diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.vanilla-2.6.16-rc2/include/linux/libata.h linux-2.6.16-rc2/include/linux/libata.h ---- linux.vanilla-2.6.16-rc2/include/linux/libata.h 2006-02-06 12:21:42.000000000 +0000 -+++ linux-2.6.16-rc2/include/linux/libata.h 2006-02-06 18:45:03.000000000 +0000 -@@ -101,6 +101,7 @@ - ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */ - ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */ - ATA_DFLAG_LBA = (1 << 3), /* device supports LBA */ -+ ATA_DFLAG_HPA = (1 << 4), /* device has an HPA */ - - ATA_DEV_UNKNOWN = 0, /* unknown device */ - ATA_DEV_ATA = 1, /* ATA device */ -@@ -133,6 +134,8 @@ - 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, -+ -+ ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */ - - /* various lengths of time */ - ATA_TMOUT_EDD = 5 * HZ, /* heuristic */ -@@ -197,6 +200,7 @@ - - /* forward declarations */ - struct scsi_device; -+struct ata_host_set; - struct ata_port_operations; - struct ata_port; - struct ata_queued_cmd; -@@ -237,8 +241,10 @@ - unsigned long irq; - unsigned int irq_flags; - unsigned long host_flags; -+ unsigned long host_set_flags; - void __iomem *mmio_base; - void *private_data; -+ struct ata_host_set *host_set; /* Return not input value */ - }; - - struct ata_host_set { -@@ -250,6 +256,9 @@ - void *private_data; - const struct ata_port_operations *ops; - struct ata_port * ports[0]; -+ unsigned long host_set_flags; -+ int simplex_claimed; /* Keep seperate in case we -+ ever need to do this locked */ - }; - - struct ata_queued_cmd { -@@ -369,6 +378,7 @@ - - void (*set_piomode) (struct ata_port *, struct ata_device *); - void (*set_dmamode) (struct ata_port *, struct ata_device *); -+ unsigned int (*mode_filter) (const struct ata_port *, struct ata_device *, unsigned int, int); - - void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf); - void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); -@@ -379,12 +389,15 @@ - void (*dev_select)(struct ata_port *ap, unsigned int device); - - void (*phy_reset) (struct ata_port *ap); -+ void (*set_mode) (struct ata_port *ap); - void (*post_set_mode) (struct ata_port *ap); - - int (*check_atapi_dma) (struct ata_queued_cmd *qc); - - void (*bmdma_setup) (struct ata_queued_cmd *qc); - void (*bmdma_start) (struct ata_queued_cmd *qc); -+ -+ void (*data_xfer) (struct ata_port *, unsigned char *, unsigned int, int); - - void (*qc_prep) (struct ata_queued_cmd *qc); - int (*qc_issue) (struct ata_queued_cmd *qc); -@@ -443,8 +456,9 @@ - extern void ata_pci_remove_one (struct pci_dev *pdev); - extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state); - extern int ata_pci_device_resume(struct pci_dev *pdev); -+extern int ata_pci_clear_simplex(struct pci_dev *pdev); - #endif /* CONFIG_PCI */ --extern int ata_device_add(const struct ata_probe_ent *ent); -+extern int ata_device_add(struct ata_probe_ent *ent); - extern void ata_host_set_remove(struct ata_host_set *host_set); - extern int ata_scsi_detect(struct scsi_host_template *sht); - extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); -@@ -491,6 +505,15 @@ - extern void ata_bmdma_irq_clear(struct ata_port *ap); - extern void ata_qc_complete(struct ata_queued_cmd *qc); - extern void ata_eng_timeout(struct ata_port *ap); -+extern void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, -+ unsigned int buflen, int write_data); -+extern void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf, -+ unsigned int buflen, int write_data); -+extern void ata_mmio_data_xfer_noirq(struct ata_port *ap, unsigned char *buf, -+ unsigned int buflen, int do_write); -+extern void ata_pio_data_xfer_noirq(struct ata_port *ap, unsigned char *buf, -+ unsigned int buflen, int do_write); -+ - extern void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, - struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)); diff --git a/packages/linux/ixp4xx-kernel/2.6.16/06-remove-extraversion.patch b/packages/linux/ixp4xx-kernel/2.6.16/06-remove-extraversion.patch index 8f2ce831b2..18ca31a42d 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/06-remove-extraversion.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/06-remove-extraversion.patch @@ -4,7 +4,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 16 --EXTRAVERSION =-rc4 +-EXTRAVERSION = -rc4-git5 +EXTRAVERSION = NAME=Sliding Snow Leopard diff --git a/packages/linux/ixp4xx-kernel/2.6.16/10-nslu2-fix-flash.patch b/packages/linux/ixp4xx-kernel/2.6.16/10-nslu2-fix-flash.patch deleted file mode 100644 index ab37b099b1..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/10-nslu2-fix-flash.patch +++ /dev/null @@ -1,14 +0,0 @@ - arch/arm/mach-ixp4xx/nslu2-setup.c | 2 -- - 1 file changed, 2 deletions(-) - ---- linux-nslu2.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-06 21:49:41.000000000 +0100 -+++ linux-nslu2/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-06 21:59:55.000000000 +0100 -@@ -27,8 +27,6 @@ static struct flash_platform_data nslu2_ - }; - - static struct resource nslu2_flash_resource = { -- .start = NSLU2_FLASH_BASE, -- .end = NSLU2_FLASH_BASE + NSLU2_FLASH_SIZE, - .flags = IORESOURCE_MEM, - }; - diff --git a/packages/linux/ixp4xx-kernel/2.6.16/61-ixp4xx-beeper-irq.patch b/packages/linux/ixp4xx-kernel/2.6.16/61-ixp4xx-beeper-irq.patch deleted file mode 100644 index 4a97bf57a5..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/61-ixp4xx-beeper-irq.patch +++ /dev/null @@ -1,13 +0,0 @@ - drivers/input/misc/ixp4xx-beeper.c | 1 + - 1 file changed, 1 insertion(+) - ---- linux-nslu2.orig/drivers/input/misc/ixp4xx-beeper.c 2006-02-06 20:37:19.000000000 +0100 -+++ linux-nslu2/drivers/input/misc/ixp4xx-beeper.c 2006-02-06 22:04:59.000000000 +0100 -@@ -19,6 +19,7 @@ - #include <linux/input.h> - #include <linux/delay.h> - #include <linux/platform_device.h> -+#include <linux/interrupt.h> - #include <asm/hardware.h> - - MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); diff --git a/packages/linux/ixp4xx-kernel/2.6.16/61-nslu2-beeper.patch b/packages/linux/ixp4xx-kernel/2.6.16/61-nslu2-beeper.patch deleted file mode 100644 index d58139429d..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/61-nslu2-beeper.patch +++ /dev/null @@ -1,32 +0,0 @@ -http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3344/1 - -NSLU2 beeper support. - -Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> - - arch/arm/mach-ixp4xx/nslu2-setup.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- linux-nslu2.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-06 20:37:01.000000000 +0100 -+++ linux-nslu2/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-06 22:21:17.000000000 +0100 -@@ -52,6 +52,12 @@ static struct platform_device nslu2_i2c_ - .num_resources = 0, - }; - -+static struct platform_device nslu2_beeper = { -+ .name = "ixp4xx-beeper", -+ .id = NSLU2_GPIO_BUZZ, -+ .num_resources = 0, -+}; -+ - static struct resource nslu2_uart_resources[] = { - { - .start = IXP4XX_UART1_BASE_PHYS, -@@ -99,6 +105,7 @@ static struct platform_device *nslu2_dev - &nslu2_i2c_controller, - &nslu2_flash, - &nslu2_uart, -+ &nslu2_beeper, - }; - - static void nslu2_power_off(void) diff --git a/packages/linux/ixp4xx-kernel/2.6.16/70-artop-latency.patch b/packages/linux/ixp4xx-kernel/2.6.16/70-artop-latency.patch index 2cda5789ce..ad3ad11999 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/70-artop-latency.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/70-artop-latency.patch @@ -1,10 +1,17 @@ +On some controllers the pci latency timer +default value does not allow burst mode. +This patch fixes the latency value if it +is <= 0x80. + +Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> + --- - drivers/scsi/pata_artop.c | 8 ++++++++ - 1 file changed, 8 insertions(+) + drivers/scsi/pata_artop.c | 7 +++++++ + 1 file changed, 7 insertions(+) ---- linux-ixp4xx.orig/drivers/scsi/pata_artop.c 2006-02-21 02:05:33.000000000 +0100 -+++ linux-ixp4xx/drivers/scsi/pata_artop.c 2006-02-21 02:49:47.000000000 +0100 -@@ -450,6 +450,14 @@ static int artop_init_one (struct pci_de +--- linux-ixp4xx.orig/drivers/scsi/pata_artop.c 2006-02-21 02:53:43.000000000 +0100 ++++ linux-ixp4xx/drivers/scsi/pata_artop.c 2006-02-21 02:54:01.000000000 +0100 +@@ -450,6 +450,13 @@ static int artop_init_one (struct pci_de pci_read_config_byte(pdev, 0x49, ®); pci_write_config_byte(pdev, 0x49, reg & ~ 0x30); @@ -15,7 +22,6 @@ + if (reg <= 0x80) + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x90); + -+ /* Enable IRQ output and burst mode */ pci_read_config_byte(pdev, 0x4a, ®); pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80); diff --git a/packages/linux/ixp4xx-kernel/2.6.16/75-dsmg600.patch b/packages/linux/ixp4xx-kernel/2.6.16/75-dsmg600.patch new file mode 100644 index 0000000000..05d467d0be --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/75-dsmg600.patch @@ -0,0 +1,353 @@ +--- + arch/arm/mach-ixp4xx/Kconfig | 8 + + arch/arm/mach-ixp4xx/Makefile | 1 + arch/arm/mach-ixp4xx/dsmg600-pci.c | 74 +++++++++++++++++ + arch/arm/mach-ixp4xx/dsmg600-setup.c | 139 +++++++++++++++++++++++++++++++++ + arch/arm/tools/mach-types | 1 + include/asm-arm/arch-ixp4xx/dsmg600.h | 62 ++++++++++++++ + include/asm-arm/arch-ixp4xx/hardware.h | 1 + include/asm-arm/arch-ixp4xx/irqs.h | 10 ++ + 8 files changed, 296 insertions(+) + +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/Kconfig 2006-02-23 18:29:02.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/Kconfig 2006-02-23 18:29:11.000000000 +0100 +@@ -85,6 +85,14 @@ config MACH_NAS100D + NAS 100d device. For more information on this platform, + see http://www.nslu2-linux.org/wiki/NAS100d/HomePage + ++config MACH_DSMG600 ++ bool ++ prompt "D-Link DSM-G600" ++ help ++ Say 'Y' here if you want your kernel to support D-Link's ++ DSM-G600 device. For more information on this platform, ++ see http://www.nslu2-linux.org/ ++ + # + # Avila and IXDP share the same source for now. Will change in future + # +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/dsmg600-pci.c 2006-02-23 18:29:11.000000000 +0100 +@@ -0,0 +1,74 @@ ++/* ++ * DSM-G600 board-level PCI initialization ++ * ++ * Copyright (c) 2006 Tower Technologies ++ * Author: Alessandro Zummo <a.zummo@towertech.it> ++ * ++ * based on ixdp425-pci.c: ++ * Copyright (C) 2002 Intel Corporation. ++ * Copyright (C) 2003-2004 MontaVista Software, Inc. ++ * ++ * Maintainer: http://www.nslu2-linux.org/ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include <linux/config.h> ++#include <linux/pci.h> ++#include <linux/init.h> ++ ++#include <asm/mach/pci.h> ++#include <asm/mach-types.h> ++ ++void __init dsmg600_pci_preinit(void) ++{ ++ set_irq_type(IRQ_DSMG600_PCI_INTA, IRQT_LOW); ++ set_irq_type(IRQ_DSMG600_PCI_INTB, IRQT_LOW); ++ set_irq_type(IRQ_DSMG600_PCI_INTC, IRQT_LOW); ++ set_irq_type(IRQ_DSMG600_PCI_INTD, IRQT_LOW); ++ set_irq_type(IRQ_DSMG600_PCI_INTE, IRQT_LOW); ++ set_irq_type(IRQ_DSMG600_PCI_INTF, IRQT_LOW); ++ ++ ixp4xx_pci_preinit(); ++} ++ ++static int __init dsmg600_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ static int pci_irq_table[DSMG600_PCI_MAX_DEV][DSMG600_PCI_IRQ_LINES] = ++ { ++ { IRQ_DSMG600_PCI_INTE, -1, -1 }, ++ { IRQ_DSMG600_PCI_INTA, -1, -1 }, ++ { IRQ_DSMG600_PCI_INTB, IRQ_DSMG600_PCI_INTC, IRQ_DSMG600_PCI_INTD }, ++ { IRQ_DSMG600_PCI_INTF, -1, -1 }, ++ }; ++ ++ int irq = -1; ++ ++ if (slot >= 1 && slot <= DSMG600_PCI_MAX_DEV && ++ pin >= 1 && pin <= DSMG600_PCI_IRQ_LINES) ++ irq = pci_irq_table[slot-1][pin-1]; ++ ++ return irq; ++} ++ ++struct hw_pci __initdata dsmg600_pci = { ++ .nr_controllers = 1, ++ .preinit = dsmg600_pci_preinit, ++ .swizzle = pci_std_swizzle, ++ .setup = ixp4xx_setup, ++ .scan = ixp4xx_scan_bus, ++ .map_irq = dsmg600_map_irq, ++}; ++ ++int __init dsmg600_pci_init(void) ++{ ++ if (machine_is_dsmg600()) ++ pci_common_init(&dsmg600_pci); ++ ++ return 0; ++} ++ ++subsys_initcall(dsmg600_pci_init); +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/dsmg600-setup.c 2006-02-23 18:29:11.000000000 +0100 +@@ -0,0 +1,139 @@ ++/* ++ * DSM-G600 board-setup ++ * ++ * Copyright (c) 2006 Tower Technologies ++ * Author: Alessandro Zummo <a.zummo@towertech.it> ++ * ++ * based ixdp425-setup.c: ++ * Copyright (C) 2003-2004 MontaVista Software, Inc. ++ * ++ * Author: Alessandro Zummo <a.zummo@towertech.it> ++ * Maintainers: http://www.nslu2-linux.org/ ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/serial.h> ++#include <linux/serial_8250.h> ++ ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/flash.h> ++ ++static struct flash_platform_data dsmg600_flash_data = { ++ .map_name = "cfi_probe", ++ .width = 2, ++}; ++ ++static struct resource dsmg600_flash_resource = { ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct platform_device dsmg600_flash = { ++ .name = "IXP4XX-Flash", ++ .id = 0, ++ .dev.platform_data = &dsmg600_flash_data, ++ .num_resources = 1, ++ .resource = &dsmg600_flash_resource, ++}; ++ ++static struct ixp4xx_i2c_pins dsmg600_i2c_gpio_pins = { ++ .sda_pin = DSMG600_SDA_PIN, ++ .scl_pin = DSMG600_SCL_PIN, ++}; ++ ++static struct platform_device dsmg600_i2c_controller = { ++ .name = "IXP4XX-I2C", ++ .id = 0, ++ .dev.platform_data = &dsmg600_i2c_gpio_pins, ++ .num_resources = 0, ++}; ++ ++static struct resource dsmg600_uart_resources[] = { ++ { ++ .start = IXP4XX_UART1_BASE_PHYS, ++ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IXP4XX_UART2_BASE_PHYS, ++ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++static struct plat_serial8250_port dsmg600_uart_data[] = { ++ { ++ .mapbase = IXP4XX_UART1_BASE_PHYS, ++ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, ++ .irq = IRQ_IXP4XX_UART1, ++ .flags = UPF_BOOT_AUTOCONF, ++ .iotype = UPIO_MEM, ++ .regshift = 2, ++ .uartclk = IXP4XX_UART_XTAL, ++ }, ++ { ++ .mapbase = IXP4XX_UART2_BASE_PHYS, ++ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++ .irq = IRQ_IXP4XX_UART2, ++ .flags = UPF_BOOT_AUTOCONF, ++ .iotype = UPIO_MEM, ++ .regshift = 2, ++ .uartclk = IXP4XX_UART_XTAL, ++ }, ++ { } ++}; ++ ++static struct platform_device dsmg600_uart = { ++ .name = "serial8250", ++ .id = PLAT8250_DEV_PLATFORM, ++ .dev.platform_data = dsmg600_uart_data, ++ .num_resources = 2, ++ .resource = dsmg600_uart_resources, ++}; ++ ++static struct platform_device *dsmg600_devices[] __initdata = { ++ &dsmg600_i2c_controller, ++ &dsmg600_flash, ++ &dsmg600_uart, ++}; ++ ++static void dsmg600_power_off(void) ++{ ++ /* enable the pwr cntl gpio */ ++// gpio_line_config(DSMG600_GPIO_PWROFF, IXP4XX_GPIO_OUT); ++ ++ /* poweroff */ ++// gpio_line_set(DSMG600_GPIO_PWROFF, IXP4XX_GPIO_HIGH); ++} ++ ++static void __init dsmg600_init(void) ++{ ++ /* The DSM-G600 has a 33MHz crystal on board - 1.01% different ++ * from the typical value. ++ */ ++ ++#ifndef FREQ ++ ixp4xx_set_board_tick_rate(66000000); ++#endif ++ ++ ixp4xx_sys_init(); ++ ++ dsmg600_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++ dsmg600_flash_resource.end = ++ IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; ++ ++ pm_power_off = dsmg600_power_off; ++ ++ platform_add_devices(dsmg600_devices, ARRAY_SIZE(dsmg600_devices)); ++} ++ ++MACHINE_START(DSMG600, "D-Link DSM-G600") ++ /* Maintainer: www.nslu2-linux.org */ ++ .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, ++ .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, ++ .boot_params = 0x00000100, ++ .map_io = ixp4xx_map_io, ++ .init_irq = ixp4xx_init_irq, ++ .timer = &ixp4xx_timer, ++ .init_machine = dsmg600_init, ++MACHINE_END +--- linux-ixp4xx.orig/arch/arm/tools/mach-types 2006-02-23 18:29:02.000000000 +0100 ++++ linux-ixp4xx/arch/arm/tools/mach-types 2006-02-23 18:29:39.000000000 +0100 +@@ -969,3 +969,4 @@ mxc300_30ads MACH_MXC30030ADS MXC30030A + fujitsu_wimaxsoc MACH_FUJITSU_WIMAXSOC FUJITSU_WIMAXSOC 956 + dualpcmodem MACH_DUALPCMODEM DUALPCMODEM 957 + gesbc9312 MACH_GESBC9312 GESBC9312 958 ++dsmg600 MACH_DSMG600 DSMG600 964 +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/dsmg600.h 2006-02-23 18:29:11.000000000 +0100 +@@ -0,0 +1,62 @@ ++/* ++ * DSM-G600 platform specific definitions ++ * ++ * Copyright (c) 2006 Tower Technologies ++ * Author: Alessandro Zummo <a.zummo@towertech.it> ++ * ++ * based on ixdp425.h: ++ * Copyright 2004 (c) MontaVista, Software, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#ifndef __ASM_ARCH_HARDWARE_H__ ++#error "Do not include this directly, instead #include <asm/hardware.h>" ++#endif ++ ++#define DSMG600_SDA_PIN 5 ++#define DSMG600_SCL_PIN 4 ++ ++/* ++ * DSMG600 PCI IRQs ++ */ ++#define DSMG600_PCI_MAX_DEV 4 ++#define DSMG600_PCI_IRQ_LINES 3 ++ ++ ++/* PCI controller GPIO to IRQ pin mappings */ ++#define DSMG600_PCI_INTA_PIN 11 ++#define DSMG600_PCI_INTB_PIN 10 ++#define DSMG600_PCI_INTC_PIN 9 ++#define DSMG600_PCI_INTD_PIN 8 ++#define DSMG600_PCI_INTE_PIN 7 ++#define DSMG600_PCI_INTF_PIN 6 ++ ++/* GPIO */ ++ ++#define DSMG600_GPIO0 0 ++#define DSMG600_GPIO1 1 ++#define DSMG600_GPIO2 2 ++#define DSMG600_GPIO3 3 ++#define DSMG600_GPIO4 4 ++#define DSMG600_GPIO5 5 ++#define DSMG600_GPIO6 6 ++#define DSMG600_GPIO7 7 ++#define DSMG600_GPIO8 8 ++#define DSMG600_GPIO9 9 ++#define DSMG600_GPIO10 10 ++#define DSMG600_GPIO11 11 ++#define DSMG600_GPIO12 12 ++#define DSMG600_GPIO13 13 ++#define DSMG600_GPIO14 14 ++#define DSMG600_GPIO15 15 ++ ++#define DSMG600_GPIO_PWRBTN DSMG600_GPIO15 /* power */ ++#define DSMG600_GPIO_RSTBTN DSMG600_GPIO3 /* reset */ ++ ++#define DSMG600_IRQ_PWRBTN IRQ_IXP4XX_GPIO15 ++#define DSMG600_IRQ_RSTBTN IRQ_IXP4XX_GPIO3 ++ ++#define DSMG600_GPIO_PWROFF DSMG600_GPIO2 /* power off */ +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/Makefile 2006-02-23 18:29:02.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/Makefile 2006-02-23 18:29:11.000000000 +0100 +@@ -10,4 +10,5 @@ obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote- + obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o + obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o + obj-$(CONFIG_MACH_NAS100D) += nas100d-pci.o nas100d-setup.o nas100d-power.o ++obj-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o dsmg600-setup.o + +--- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/hardware.h 2006-02-23 18:29:02.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/hardware.h 2006-02-23 18:29:11.000000000 +0100 +@@ -46,5 +46,6 @@ extern unsigned int processor_id; + #include "prpmc1100.h" + #include "nslu2.h" + #include "nas100d.h" ++#include "dsmg600.h" + + #endif /* _ASM_ARCH_HARDWARE_H */ +--- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/irqs.h 2006-02-23 18:29:02.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/irqs.h 2006-02-23 18:29:11.000000000 +0100 +@@ -109,4 +109,14 @@ + #define IRQ_NAS100D_PCI_INTD IRQ_IXP4XX_GPIO8 + #define IRQ_NAS100D_PCI_INTE IRQ_IXP4XX_GPIO7 + ++/* ++ * D-Link DSM-G600 board IRQs ++ */ ++#define IRQ_DSMG600_PCI_INTA IRQ_IXP4XX_GPIO11 ++#define IRQ_DSMG600_PCI_INTB IRQ_IXP4XX_GPIO10 ++#define IRQ_DSMG600_PCI_INTC IRQ_IXP4XX_GPIO9 ++#define IRQ_DSMG600_PCI_INTD IRQ_IXP4XX_GPIO8 ++#define IRQ_DSMG600_PCI_INTE IRQ_IXP4XX_GPIO7 ++#define IRQ_DSMG600_PCI_INTF IRQ_IXP4XX_GPIO6 ++ + #endif diff --git a/packages/linux/ixp4xx-kernel/2.6.16/80-nas100d-fix-i2c.patch b/packages/linux/ixp4xx-kernel/2.6.16/80-nas100d-fix-i2c.patch deleted file mode 100644 index 6ba1fd7b62..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/80-nas100d-fix-i2c.patch +++ /dev/null @@ -1,18 +0,0 @@ -http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3343/1 - - include/asm-arm/arch-ixp4xx/nas100d.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- linux-nslu2.orig/include/asm-arm/arch-ixp4xx/nas100d.h 2006-02-06 20:37:38.000000000 +0100 -+++ linux-nslu2/include/asm-arm/arch-ixp4xx/nas100d.h 2006-02-09 14:33:49.000000000 +0100 -@@ -19,8 +19,8 @@ - #error "Do not include this directly, instead #include <asm/hardware.h>" - #endif - --#define NAS100D_SDA_PIN 6 --#define NAS100D_SCL_PIN 5 -+#define NAS100D_SDA_PIN 5 -+#define NAS100D_SCL_PIN 6 - - /* - * NAS100D PCI IRQs diff --git a/packages/linux/ixp4xx-kernel/2.6.16/81-nslu2-power.patch b/packages/linux/ixp4xx-kernel/2.6.16/81-nslu2-power.patch deleted file mode 100644 index 0937c76181..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/81-nslu2-power.patch +++ /dev/null @@ -1,17 +0,0 @@ -http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3342/1 - - arch/arm/mach-ixp4xx/nslu2-power.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- linux-nslu2.orig/arch/arm/mach-ixp4xx/nslu2-power.c 2006-02-06 20:37:01.000000000 +0100 -+++ linux-nslu2/arch/arm/mach-ixp4xx/nslu2-power.c 2006-02-06 22:34:46.000000000 +0100 -@@ -77,6 +77,9 @@ static int __init nslu2_power_init(void) - - static void __exit nslu2_power_exit(void) - { -+ if (!(machine_is_nslu2())) -+ return; -+ - free_irq(NSLU2_RB_IRQ, NULL); - free_irq(NSLU2_PB_IRQ, NULL); - } diff --git a/packages/linux/ixp4xx-kernel/2.6.16/85-timer.patch b/packages/linux/ixp4xx-kernel/2.6.16/85-timer.patch index 3ee670f1e9..83951c2574 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/85-timer.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/85-timer.patch @@ -4,9 +4,9 @@ include/asm-arm/arch-ixp4xx/timex.h | 23 +++-- 4 files changed, 176 insertions(+), 22 deletions(-) ---- linux-nslu2.orig/arch/arm/mach-ixp4xx/common.c 2006-02-06 20:37:01.000000000 +0100 -+++ linux-nslu2/arch/arm/mach-ixp4xx/common.c 2006-02-06 22:34:55.000000000 +0100 -@@ -241,36 +241,165 @@ void __init ixp4xx_init_irq(void) +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/common.c 2006-02-23 18:27:49.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/common.c 2006-02-23 18:30:49.000000000 +0100 +@@ -247,36 +247,165 @@ void __init ixp4xx_init_irq(void) * IXP4xx timer tick * We use OS timer1 on the CPU for the timer tick and the timestamp * counter as a source of real clock ticks to account for missed jiffies. @@ -181,7 +181,7 @@ write_sequnlock(&xtime_lock); -@@ -283,17 +412,30 @@ static struct irqaction ixp4xx_timer_irq +@@ -289,17 +418,30 @@ static struct irqaction ixp4xx_timer_irq .handler = ixp4xx_timer_interrupt, }; @@ -214,13 +214,13 @@ /* Connect the interrupt handler and enable the interrupt */ setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq); -@@ -356,4 +498,3 @@ void __init ixp4xx_sys_init(void) +@@ -362,4 +504,3 @@ void __init ixp4xx_sys_init(void) printk("IXP4xx: Using %luMiB expansion bus window size\n", ixp4xx_exp_bus_size >> 20); } - ---- linux-nslu2.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-06 22:31:04.000000000 +0100 -+++ linux-nslu2/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-06 22:34:55.000000000 +0100 +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-23 18:27:49.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-23 18:30:49.000000000 +0100 @@ -119,6 +119,11 @@ static void nslu2_power_off(void) static void __init nslu2_init(void) @@ -232,9 +232,9 @@ + ixp4xx_sys_init(); - pm_power_off = nslu2_power_off; ---- linux-nslu2.orig/include/asm-arm/arch-ixp4xx/nslu2.h 2006-02-06 20:37:38.000000000 +0100 -+++ linux-nslu2/include/asm-arm/arch-ixp4xx/nslu2.h 2006-02-06 22:34:55.000000000 +0100 + nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); +--- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/nslu2.h 2006-02-23 18:27:12.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/nslu2.h 2006-02-23 18:30:49.000000000 +0100 @@ -35,11 +35,6 @@ #define NSLU2_PCI_INTD_PIN 8 @@ -247,8 +247,8 @@ /* GPIO */ #define NSLU2_GPIO0 0 ---- linux-nslu2.orig/include/asm-arm/arch-ixp4xx/timex.h 2006-01-25 19:12:27.000000000 +0100 -+++ linux-nslu2/include/asm-arm/arch-ixp4xx/timex.h 2006-02-06 22:34:55.000000000 +0100 +--- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/timex.h 2006-02-23 18:27:12.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/timex.h 2006-02-23 18:30:49.000000000 +0100 @@ -6,10 +6,23 @@ #include <asm/hardware.h> diff --git a/packages/linux/ixp4xx-kernel/2.6.16/91-maclist.patch b/packages/linux/ixp4xx-kernel/2.6.16/91-maclist.patch index 72b9fa9a7d..34579183d0 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/91-maclist.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/91-maclist.patch @@ -10,10 +10,16 @@ code. Signed-off-by: John Bowler <jbowler@acm.org> -diff -rup linux-2.6.15.1/.pc/91-maclist.patch/drivers/net/Kconfig linux-2.6.15.1/drivers/net/Kconfig ---- linux-2.6.15/drivers/net/Kconfig 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/net/Kconfig 1970-01-01 00:00:00.000000000 +0000 -@@ -166,6 +166,21 @@ config NET_ETHERNET +--- + drivers/net/Kconfig | 15 + + drivers/net/Makefile | 1 + drivers/net/maclist.c | 465 ++++++++++++++++++++++++++++++++++++++++++++++++++ + include/net/maclist.h | 49 +++++ + 4 files changed, 530 insertions(+) + +--- linux-ixp4xx.orig/drivers/net/Kconfig 2006-02-23 18:27:12.000000000 +0100 ++++ linux-ixp4xx/drivers/net/Kconfig 2006-02-23 18:30:54.000000000 +0100 +@@ -177,6 +177,21 @@ config NET_ETHERNET kernel: saying N will just cause the configurator to skip all the questions about Ethernet network cards. If unsure, say N. @@ -35,10 +41,9 @@ diff -rup linux-2.6.15.1/.pc/91-maclist.patch/drivers/net/Kconfig linux-2.6.15.1 config MII tristate "Generic Media Independent Interface device support" depends on NET_ETHERNET -diff -rup linux-2.6.15.1/.pc/91-maclist.patch/drivers/net/Makefile linux-2.6.15.1/drivers/net/Makefile ---- linux-2.6.15/drivers/net/Makefile 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/net/Makefile 1970-01-01 00:00:00.000000000 +0000 -@@ -70,6 +70,7 @@ obj-$(CONFIG_RIONET) += rionet.o +--- linux-ixp4xx.orig/drivers/net/Makefile 2006-02-23 18:27:12.000000000 +0100 ++++ linux-ixp4xx/drivers/net/Makefile 2006-02-23 18:30:54.000000000 +0100 +@@ -74,6 +74,7 @@ obj-$(CONFIG_RIONET) += rionet.o # end link order section # @@ -46,9 +51,8 @@ diff -rup linux-2.6.15.1/.pc/91-maclist.patch/drivers/net/Makefile linux-2.6.15. obj-$(CONFIG_MII) += mii.o obj-$(CONFIG_PHYLIB) += phy/ -diff -rup linux-2.6.15.1/.pc/91-maclist.patch/drivers/net/maclist.c linux-2.6.15.1/drivers/net/maclist.c ---- linux-2.6.15/drivers/net/maclist.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/net/maclist.c 1970-01-01 00:00:00.000000000 +0000 +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/drivers/net/maclist.c 2006-02-23 18:30:54.000000000 +0100 @@ -0,0 +1,465 @@ +/* + * drivers/net/maclist.c @@ -238,7 +242,7 @@ diff -rup linux-2.6.15.1/.pc/91-maclist.patch/drivers/net/maclist.c linux-2.6.15 +void maclist_read(u8 (*id)[6], u32 key) { + int count, index; + maclist_entry_t *entry, *entry_to_allocate; -+ ++ + /* Do this under a write lock to avoid the SMP race + * where we find the key isn't assigned, drop the lock, + * have another CPU assign it, then assign it on this @@ -515,9 +519,8 @@ diff -rup linux-2.6.15.1/.pc/91-maclist.patch/drivers/net/maclist.c linux-2.6.15 + +module_init(maclist_init); +module_exit(maclist_exit); -diff -rup linux-2.6.15.1/.pc/91-maclist.patch/include/net/maclist.h linux-2.6.15.1/include/net/maclist.h ---- linux-2.6.15/include/net/maclist.h 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/include/net/maclist.h 1970-01-01 00:00:00.000000000 +0000 +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/include/net/maclist.h 2006-02-23 18:30:54.000000000 +0100 @@ -0,0 +1,49 @@ +#ifndef _MACLIST_H +#define _MACLIST_H 1 diff --git a/packages/linux/ixp4xx-kernel/2.6.16/92-nslu2-maclist.patch b/packages/linux/ixp4xx-kernel/2.6.16/92-nslu2-maclist.patch index f08efacb64..298a3d92bb 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/92-nslu2-maclist.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/92-nslu2-maclist.patch @@ -2,8 +2,8 @@ arch/arm/mach-ixp4xx/nslu2-setup.c | 39 +++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) ---- linux-nslu2.orig/arch/arm/mach-ixp4xx/Kconfig 2006-02-06 22:35:26.000000000 +0100 -+++ linux-nslu2/arch/arm/mach-ixp4xx/Kconfig 2006-02-06 22:35:31.000000000 +0100 +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/Kconfig 2006-02-23 18:30:58.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/Kconfig 2006-02-23 18:31:00.000000000 +0100 @@ -11,8 +11,8 @@ comment "IXP4xx Platforms" # This entry is placed on top because otherwise it would have # been shown as a submenu. @@ -15,8 +15,8 @@ help Say 'Y' here if you want your kernel to support Linksys's NSLU2 NAS device. For more information on this platform, ---- linux-nslu2.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-06 22:34:55.000000000 +0100 -+++ linux-nslu2/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-06 22:35:31.000000000 +0100 +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-23 18:30:49.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-23 18:31:00.000000000 +0100 @@ -16,11 +16,14 @@ #include <linux/kernel.h> #include <linux/serial.h> @@ -81,4 +81,4 @@ + ixp4xx_sys_init(); - pm_power_off = nslu2_power_off; + nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); diff --git a/packages/linux/ixp4xx-kernel/2.6.16/93-loft-maclist.patch b/packages/linux/ixp4xx-kernel/2.6.16/93-loft-maclist.patch deleted file mode 100644 index ffda1136ef..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/93-loft-maclist.patch +++ /dev/null @@ -1,96 +0,0 @@ -add loft support for setting the maclist from EEPROM - -Signed-off-by: John Bowler <jbowler@acm.org> - ---- linux-2.6.15/arch/arm/mach-ixp4xx/ixdp425-setup.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/arch/arm/mach-ixp4xx/ixdp425-setup.c 1970-01-01 00:00:00.000000000 +0000 -@@ -14,6 +14,7 @@ - #include <linux/serial.h> - #include <linux/tty.h> - #include <linux/serial_8250.h> -+#include <linux/eeprom.h> - - #include <asm/types.h> - #include <asm/setup.h> -@@ -24,6 +25,8 @@ - #include <asm/mach/arch.h> - #include <asm/mach/flash.h> - -+#include <net/maclist.h> -+ - static struct flash_platform_data ixdp425_flash_data = { - .map_name = "cfi_probe", - .width = 2, -@@ -188,9 +191,62 @@ MACHINE_END - /* - * Loft is functionally equivalent to Avila except that it has a - * different number for the maximum PCI devices. The MACHINE -- * structure below is identical to Avila except for the comment. -+ * structure below is identical to Avila except for the and -+ * the use of a loft specific init. -+ * -+ * The loft init registers a notifier on the on-board EEPROM to -+ * detect the MAC addresses. -+ * NOTE: this probably works for all Gateworks Avila boards and -+ * maybe the ixdp425 too. - */ - #ifdef CONFIG_MACH_LOFT -+/* -+ * When the EEPROM is added the MAC address are read from it. -+ */ -+static void loft_eeprom_add(int address, int kind, struct kobject *kobj, -+ struct bin_attribute *eeprom_attr) { -+ /* The MACs are the first 12 bytes in the eeprom at address 0x51 */ -+ if (address == 0x51) { -+ ssize_t retlen; -+ char data[12]; -+ -+ /* Two Macs, one at 0, the other at 6, maclist_add will -+ * complain if the ID is not a valid MAC. -+ */ -+ retlen = eeprom_attr->read(kobj, data, 0, sizeof data); -+ if (retlen >= 6) { -+ u8 mac[6]; -+ memcpy(mac, data+0, sizeof mac); -+ printk(KERN_INFO "LOFT MAC[0]: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -+ maclist_add(mac); -+ } -+ if (retlen >= 12) { -+ u8 mac[6]; -+ memcpy(mac, data+6, sizeof mac); -+ printk(KERN_INFO "LOFT MAC[1]: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -+ maclist_add(mac); -+ } -+ } -+} -+ -+static struct eeprom_notifier loft_eeprom_notifier = { -+ .add = loft_eeprom_add -+}; -+ -+static void __init loft_init(void) -+{ -+ /* The EEPROM has two ethernet MACs embedded in it which we need, -+ * that is all this notifier does. -+ */ -+ register_eeprom_user(&loft_eeprom_notifier); -+ -+ ixp4xx_sys_init(); -+ -+ platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices)); -+} -+ - MACHINE_START(LOFT, "Giant Shoulder Inc Loft board") - /* Maintainer: Tom Billman <kernel@giantshoulderinc.com> */ - .phys_ram = PHYS_OFFSET, -@@ -200,7 +256,7 @@ MACHINE_START(LOFT, "Giant Shoulder Inc - .init_irq = ixp4xx_init_irq, - .timer = &ixp4xx_timer, - .boot_params = 0x0100, -- .init_machine = ixdp425_init, -+ .init_machine = loft_init, - MACHINE_END - #endif - diff --git a/packages/linux/ixp4xx-kernel/2.6.16/94-nslu2-setup.patch b/packages/linux/ixp4xx-kernel/2.6.16/94-nslu2-setup.patch index 6a1c8b9783..3effbc7711 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/94-nslu2-setup.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/94-nslu2-setup.patch @@ -7,8 +7,8 @@ Signed-off-by: John Bowler <jbowler@acm.org> arch/arm/mach-ixp4xx/nslu2-setup.c | 45 ++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) ---- linux-nslu2.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-06 22:35:31.000000000 +0100 -+++ linux-nslu2/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-06 22:43:44.000000000 +0100 +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-23 18:31:00.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-23 18:31:04.000000000 +0100 @@ -18,6 +18,8 @@ #include <linux/serial_8250.h> #include <linux/mtd/mtd.h> @@ -18,7 +18,7 @@ Signed-off-by: John Bowler <jbowler@acm.org> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> -@@ -170,11 +172,52 @@ static void __init nslu2_init(void) +@@ -174,11 +176,52 @@ static void __init nslu2_init(void) platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices)); } diff --git a/packages/linux/ixp4xx-kernel/2.6.16/950-leds-timer.patch b/packages/linux/ixp4xx-kernel/2.6.16/950-leds-timer.patch deleted file mode 100644 index c44ef62ee7..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/950-leds-timer.patch +++ /dev/null @@ -1,151 +0,0 @@ -Fix for a bug in led-triggers.c plus an update to the -timer trigger code to allow for fractional frequency -values and to correct the evaluation of frequency so -that it is the actual frequency. - -Signed-off-by: John Bowler <jbowler@acm.org> - ---- linux-2.6.15/drivers/leds/led-triggers.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/led-triggers.c 1970-01-01 00:00:00.000000000 +0000 -@@ -98,7 +98,7 @@ void led_trigger_event(struct led_trigge - if (!trigger) - return; - -- read_lock(&trigger->led_devs); -+ read_lock(&trigger->leddev_list_lock); - list_for_each(entry, &trigger->led_devs) { - struct led_device *led_dev; - -@@ -107,7 +107,7 @@ void led_trigger_event(struct led_trigge - led_set_brightness(led_dev, brightness); - write_unlock(&led_dev->lock); - } -- read_unlock(&trigger->led_devs); -+ read_unlock(&trigger->leddev_list_lock); - } - - /* Caller must ensure led_dev->lock held for write */ ---- linux-2.6.15/drivers/leds/ledtrig-timer.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/ledtrig-timer.c 1970-01-01 00:00:00.000000000 +0000 -@@ -12,6 +12,7 @@ - */ - - #include <linux/config.h> -+#include <linux/ctype.h> - #include <linux/module.h> - #include <linux/kernel.h> - #include <linux/init.h> -@@ -61,21 +62,19 @@ static void led_timer_function(unsigned - static void led_timer_setdata(struct led_device *led_dev, unsigned long duty, unsigned long frequency) - { - struct timer_trig_data *timer_data = led_dev->trigger_data; -- signed long duty1; -- -- if (frequency > 500) -- frequency = 500; - - if (duty > 100) - duty = 100; - -- duty1 = duty - 50; -- - timer_data->duty = duty; - timer_data->frequency = frequency; - if (frequency != 0) { -- timer_data->delay_on = (50 - duty1) * 1000 / 50 / frequency; -- timer_data->delay_off = (50 + duty1) * 1000 / 50 / frequency; -+ timer_data->delay_on = duty * 10000U / frequency; -+ if (timer_data->delay_on == 0) -+ timer_data->delay_on = 1; -+ timer_data->delay_off = (100U-duty) * 10000U / frequency; -+ if (timer_data->delay_off == 0) -+ timer_data->delay_off = 1; - } - - mod_timer(&timer_data->timer, jiffies); -@@ -100,8 +99,8 @@ static ssize_t led_duty_store(struct cla - struct timer_trig_data *timer_data; - int ret = -EINVAL; - char *after; -- - unsigned long state = simple_strtoul(buf, &after, 10); -+ - if (after - buf > 0) { - ret = after - buf; - write_lock(&led_dev->lock); -@@ -118,32 +117,63 @@ static ssize_t led_frequency_show(struct - { - struct led_device *led_dev = dev->class_data; - struct timer_trig_data *timer_data; -+ unsigned long freq000; - - read_lock(&led_dev->lock); - timer_data = led_dev->trigger_data; -- sprintf(buf, "%lu\n", timer_data->frequency); -+ freq000 = timer_data->frequency; - read_unlock(&led_dev->lock); - -+ if (freq000 % 1000) -+ sprintf(buf, "%lu.%.3lu\n", freq000 / 1000, freq000 % 1000); -+ else -+ sprintf(buf, "%lu\n", freq000 / 1000); -+ - return strlen(buf) + 1; - } - - static ssize_t led_frequency_store(struct class_device *dev, const char *buf, size_t size) - { - struct led_device *led_dev = dev->class_data; -- struct timer_trig_data *timer_data; -- int ret = -EINVAL; -- char *after; -+ size_t rc = 0; -+ unsigned long freq000 = 0; -+ int have_digit = 0; -+ -+ while (rc < size && isspace(buf[rc])) -+ ++rc; -+ if (rc >= size) -+ return rc; -+ -+ /* number before decimal point */ -+ while (rc < size && isdigit(buf[rc])) -+ freq000 *= 10, freq000 += buf[rc++] - '0', have_digit = 1; -+ -+ if (rc < size && (buf[rc] == '.' || buf[rc] == ',')) { -+ int dp = 0; -+ ++rc; -+ while (rc < size && isdigit(buf[rc])) { -+ if (++dp <= 3) -+ freq000 *= 10, freq000 += buf[rc] - '0'; -+ ++rc; -+ have_digit = 1; -+ } -+ while (++dp <= 3) -+ freq000 *= 10; -+ } else -+ freq000 *= 1000; - -- unsigned long state = simple_strtoul(buf, &after, 10); -- if (after - buf > 0) { -- ret = after - buf; -- write_lock(&led_dev->lock); -- timer_data = led_dev->trigger_data; -- led_timer_setdata(led_dev, timer_data->duty, state); -- write_unlock(&led_dev->lock); -+ if (!have_digit) -+ return -EINVAL; -+ -+ write_lock(&led_dev->lock); -+ { -+ struct timer_trig_data *timer_data = led_dev->trigger_data; -+ led_timer_setdata(led_dev, timer_data->duty, freq000); - } -+ write_unlock(&led_dev->lock); - -- return ret; -+ -+ return rc; - } - - static CLASS_DEVICE_ATTR(duty, 0644, led_duty_show, led_duty_store); diff --git a/packages/linux/ixp4xx-kernel/2.6.16/96-loft-leds.patch b/packages/linux/ixp4xx-kernel/2.6.16/96-loft-leds.patch deleted file mode 100644 index 60fcf52cbb..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/96-loft-leds.patch +++ /dev/null @@ -1,62 +0,0 @@ -NEW_LEDS support for the loft board - -Signed-off-by: John Bowler <jbowler@acm.org> - ---- linux-2.6.15/arch/arm/mach-ixp4xx/ixdp425-setup.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/arch/arm/mach-ixp4xx/ixdp425-setup.c 1970-01-01 00:00:00.000000000 +0000 -@@ -15,6 +15,7 @@ - #include <linux/tty.h> - #include <linux/serial_8250.h> - #include <linux/eeprom.h> -+#include <linux/leds.h> - - #include <asm/types.h> - #include <asm/setup.h> -@@ -200,6 +201,29 @@ MACHINE_END - * maybe the ixdp425 too. - */ - #ifdef CONFIG_MACH_LOFT -+#ifdef CONFIG_LEDS_CLASS -+static struct resource loft_led_resources[] = { -+ { -+ .name = "ready", /* green led, also J8 pin 7 */ -+ .start = 3, -+ .end = 3, -+ .flags = IXP4XX_GPIO_LOW, -+ }, -+}; -+ -+static struct platform_device loft_leds = { -+ .name = "IXP4XX-GPIO-LED", -+ .id = -1, -+ .num_resources = ARRAY_SIZE(loft_led_resources), -+ .resource = loft_led_resources, -+}; -+#endif -+ -+static struct platform_device *loft_devices[] __initdata = { -+ &ixdp425_i2c_controller, -+ &ixdp425_flash, -+}; -+ - /* - * When the EEPROM is added the MAC address are read from it. - */ -@@ -244,7 +268,16 @@ static void __init loft_init(void) - - ixp4xx_sys_init(); - -- platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices)); -+ /* Put the UART in first for debugging, don't care if it fails. */ -+ (void)platform_device_register(&ixdp425_uart); -+ -+ /* These should work... */ -+ platform_add_devices(loft_devices, ARRAY_SIZE(loft_devices)); -+ -+#ifdef CONFIG_LEDS_CLASS -+ /* We don't care if this fails. */ -+ (void)platform_device_register(&loft_leds); -+#endif - } - - MACHINE_START(LOFT, "Giant Shoulder Inc Loft board") diff --git a/packages/linux/ixp4xx-kernel/2.6.16/96-nslu2-leds.patch b/packages/linux/ixp4xx-kernel/2.6.16/96-nslu2-leds.patch index 83043d9c2d..6b3b8d7d39 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/96-nslu2-leds.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/96-nslu2-leds.patch @@ -5,8 +5,8 @@ Signed-off-by: John Bowler <jbowler@acm.org> arch/arm/mach-ixp4xx/nslu2-setup.c | 51 ++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) ---- linux-nslu2.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-01-23 02:13:58.000000000 +0100 -+++ linux-nslu2/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-01-23 02:14:51.000000000 +0100 +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-21 02:54:05.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-21 02:54:05.000000000 +0100 @@ -17,6 +17,9 @@ #include <linux/serial.h> #include <linux/serial_8250.h> @@ -17,7 +17,7 @@ Signed-off-by: John Bowler <jbowler@acm.org> #include <asm/setup.h> #include <asm/memory.h> -@@ -50,6 +53,42 @@ static struct ixp4xx_i2c_pins nslu2_i2c_ +@@ -48,6 +51,42 @@ static struct ixp4xx_i2c_pins nslu2_i2c_ .scl_pin = NSLU2_SCL_PIN, }; @@ -60,7 +60,7 @@ Signed-off-by: John Bowler <jbowler@acm.org> static struct platform_device nslu2_i2c_controller = { .name = "IXP4XX-I2C", .id = 0, -@@ -109,7 +148,6 @@ static struct platform_device nslu2_uart +@@ -107,7 +146,6 @@ static struct platform_device nslu2_uart static struct platform_device *nslu2_devices[] __initdata = { &nslu2_i2c_controller, &nslu2_flash, @@ -68,7 +68,7 @@ Signed-off-by: John Bowler <jbowler@acm.org> &nslu2_beeper, }; -@@ -171,7 +209,18 @@ static void __init nslu2_init(void) +@@ -173,7 +211,18 @@ static void __init nslu2_init(void) pm_power_off = nslu2_power_off; diff --git a/packages/linux/ixp4xx-kernel/2.6.16/96-pata-ixp4xx.patch b/packages/linux/ixp4xx-kernel/2.6.16/96-pata-ixp4xx.patch new file mode 100644 index 0000000000..1c08150c45 --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/96-pata-ixp4xx.patch @@ -0,0 +1,299 @@ +--- + drivers/scsi/Kconfig | 11 +- + drivers/scsi/Makefile | 1 + drivers/scsi/libata-core.c | 4 + drivers/scsi/pata_ixp4xx.c | 242 +++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 255 insertions(+), 3 deletions(-) + +--- linux-ixp4xx.orig/drivers/scsi/Kconfig 2006-02-24 18:13:55.000000000 +0100 ++++ linux-ixp4xx/drivers/scsi/Kconfig 2006-02-24 18:50:19.000000000 +0100 +@@ -903,11 +903,20 @@ config SCSI_PATA_WINBOND + tristate "Winbond SL82C105 PATA support" + depends on SCSI_SATA && PCI + help +- This option enables support for SL82C105 PATA devices found in the ++ This option enables support for SL82C105 PATAll devices found in the + Netwinder and some other systems + + If unsure, say N. + ++config SCSI_PATA_IXP4XX ++ tristate "IXP4XX Compact FLash support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for a Compact Flash connected on ++ the ixp4xx expansion bus. ++ ++ If unsure, say N. ++ + + config SCSI_BUSLOGIC + tristate "BusLogic SCSI support" +--- linux-ixp4xx.orig/drivers/scsi/Makefile 2006-02-24 18:13:55.000000000 +0100 ++++ linux-ixp4xx/drivers/scsi/Makefile 2006-02-24 18:16:46.000000000 +0100 +@@ -174,6 +174,7 @@ obj-$(CONFIG_SCSI_PATA_VIA) += libata.o + obj-$(CONFIG_SCSI_PATA_WINBOND) += libata.o pata_sl82c105.o + obj-$(CONFIG_SCSI_ATA_GENERIC) += libata.o ata_generic.o + obj-$(CONFIG_SCSI_PATA_LEGACY) += libata.o pata_legacy.o ++obj-$(CONFIG_SCSI_PATA_IXP4XX) += libata.o pata_ixp4xx.o + + obj-$(CONFIG_ARM) += arm/ + +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/drivers/scsi/pata_ixp4xx.c 2006-02-24 18:43:02.000000000 +0100 +@@ -0,0 +1,242 @@ ++/* ++ * pata-ixp4xx.c - Legacy port PATA/SATA controller driver. ++ * Copyright (c) 2006 Tower Technologies ++ * ++ * An ATA driver to handle a Compact Flash connected ++ * to the ixp4xx expansion bus. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/libata.h> ++#include <scsi/scsi_host.h> ++ ++#define DRV_NAME "ixp4xx" ++#define DRV_VERSION "0.0.2" ++ ++/* XXX remove when converting to platform driver */ ++#define IXP4XX_IDE_BASE IXP4XX_EXP_BUS_BASE(1) ++#define IXP4XX_IDE_IRQ IRQ_IXP4XX_GPIO12 ++#define IXP4XX_IDE_CONTROL 0x1e ++#define IXP4XX_IDE_INT 12 ++#define IXP4XX_IDE_CS1_BITS 0xbfff0043 ++#define IXP4XX_IDE_PIO_MASK 0x1f ++ ++#ifdef __ARMEB__ ++#define ixp4xx_writew(data,addr) writew(data,addr) ++#define ixp4xx_readw(addr) readw(addr) ++#else ++#define ixp4xx_writew(data,addr) writew(le16_to_cpu(data),addr) ++#define ixp4xx_readw(addr) cpu_to_le16(readw(addr)) ++#endif ++ ++static struct ata_host_set *ixp4xx_host; ++ ++static unsigned int ixp4xx_mode_filter(const struct ata_port *ap, ++ struct ata_device *adev, unsigned int mask, int shift) ++{ ++ if (shift != ATA_SHIFT_PIO) ++ return 0; ++ return mask; ++} ++ ++static void ixp4xx_set_mode(struct ata_port *ap) ++{ ++ int i; ++ ++ for (i = 0; i < ATA_MAX_DEVICES; i++) { ++ struct ata_device *dev = &ap->device[i]; ++ if (ata_dev_present(dev)) { ++ dev->pio_mode = XFER_PIO_0; ++ dev->xfer_mode = XFER_PIO_0; ++ dev->xfer_shift = ATA_SHIFT_PIO; ++ dev->flags |= ATA_DFLAG_PIO; ++ } ++ } ++} ++ ++static void ixp4xx_phy_reset(struct ata_port *ap) ++{ ++ ap->cbl = ATA_CBL_PATA40; ++ ata_port_probe(ap); ++ ata_bus_reset(ap); ++} ++ ++void ixp4xx_mmio_data_xfer(struct ata_port *ap, struct ata_device *adev, ++ unsigned char *buf, unsigned int buflen, int write_data) ++{ ++ unsigned int i; ++ unsigned int words = buflen >> 1; ++ u16 *buf16 = (u16 *) buf; ++ void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr; ++ ++ /* set the expansion bus in 16bit mode and restore ++ * 8 bit mode after the transaction. ++ */ ++ *IXP4XX_EXP_CS1 &= ~(0x00000001); ++ ++ /* Transfer multiple of 2 bytes */ ++ if (write_data) { ++ for (i = 0; i < words; i++) ++ writew(buf16[i], mmio); ++ } else { ++ for (i = 0; i < words; i++) ++ buf16[i] = readw(mmio); ++ } ++ ++ /* Transfer trailing 1 byte, if any. */ ++ if (unlikely(buflen & 0x01)) { ++ u16 align_buf[1] = { 0 }; ++ unsigned char *trailing_buf = buf + buflen - 1; ++ ++ if (write_data) { ++ memcpy(align_buf, trailing_buf, 1); ++ writew(le16_to_cpu(align_buf[0]), mmio); ++ } else { ++ align_buf[0] = cpu_to_le16(readw(mmio)); ++ memcpy(trailing_buf, align_buf, 1); ++ } ++ } ++ ++ *IXP4XX_EXP_CS1 |= 0x00000001; ++} ++ ++void ixp4xx_host_stop(struct ata_host_set *host_set) ++{ ++ ata_host_stop(host_set); ++ release_region(IXP4XX_IDE_BASE, 0x1000); ++} ++ ++static struct scsi_host_template ixp4xx_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, ++// .ordered_flush = 1, ++}; ++ ++static struct ata_port_operations ixp4xx_port_ops = { ++ .set_mode = ixp4xx_set_mode, ++ .mode_filter = ixp4xx_mode_filter, ++ ++ .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, ++ ++ .qc_prep = ata_qc_prep, ++ .qc_issue = ata_qc_issue_prot, ++ .eng_timeout = ata_eng_timeout, ++ .data_xfer = ixp4xx_mmio_data_xfer, ++ ++ .irq_handler = ata_interrupt, ++ .irq_clear = ata_bmdma_irq_clear, ++ ++ .port_start = ata_port_start, ++ .port_stop = ata_port_stop, ++ .host_stop = ixp4xx_host_stop, ++ ++ .phy_reset = ixp4xx_phy_reset, ++}; ++ ++/* adjust the addresses to handle the address swizzling of the ++ * ixp4xx in little endian mode. ++ */ ++#ifndef __ARMEB__ ++void ixp4xx_fix_le_ports(struct ata_ioports *ioaddr) ++{ ++ ioaddr->data_addr ^= 0x02; ++ ioaddr->cmd_addr ^= 0x03; ++ ioaddr->altstatus_addr ^= 0x03; ++ ioaddr->ctl_addr ^= 0x03; ++ ioaddr->error_addr ^= 0x03; ++ ioaddr->feature_addr ^= 0x03; ++ ioaddr->nsect_addr ^= 0x03; ++ ioaddr->lbal_addr ^= 0x03; ++ ioaddr->lbam_addr ^= 0x03; ++ ioaddr->lbah_addr ^= 0x03; ++ ioaddr->device_addr ^= 0x03; ++ ioaddr->status_addr ^= 0x03; ++ ioaddr->command_addr ^= 0x03; ++} ++#endif ++ ++static __init int ixp4xx_init_one(unsigned long base, unsigned int irq) ++{ ++ int ret; ++ struct ata_probe_ent ae; ++ ++ memset(&ae, 0, sizeof(struct ata_probe_ent)); ++ INIT_LIST_HEAD(&ae.node); ++ ++ ae.mmio_base = ioremap(base, 0x1000); ++ if (ae.mmio_base == NULL) ++ return -ENOMEM; ++ ++ if (request_region(base, 0x1000, "pata_ixp4xx") == NULL) ++ return -EBUSY; ++ ++ ae.dev = NULL; ++ ae.port_ops = &ixp4xx_port_ops; ++ ae.sht = &ixp4xx_sht; ++ ae.n_ports = 1; ++ ae.pio_mask = IXP4XX_IDE_PIO_MASK; ++ ae.irq = irq; ++ ae.irq_flags = 0; ++ ae.host_flags = ATA_FLAG_IRQ_MASK | ATA_FLAG_MMIO; ++ ++ ae.port[0].cmd_addr = (unsigned long) ae.mmio_base; ++ ae.port[0].altstatus_addr = (unsigned long) ae.mmio_base + IXP4XX_IDE_CONTROL; ++ ae.port[0].ctl_addr = (unsigned long) ae.mmio_base + IXP4XX_IDE_CONTROL; ++ ata_std_ports(&ae.port[0]); ++ ++#ifndef __ARMEB__ ++ ixp4xx_fix_le_ports(&ae.port[0]); ++#endif ++ ret = ata_device_add(&ae); ++ if (ret == 0) ++ return -ENODEV; ++ ++ ixp4xx_host = ae.host_set; ++ return 0; ++} ++ ++static __init int ixp4xx_init(void) ++{ ++ gpio_line_config(IXP4XX_IDE_INT, IXP4XX_GPIO_IN | IXP4XX_GPIO_STYLE_ACTIVE_HIGH); ++ ++ *IXP4XX_EXP_CS1 |= IXP4XX_IDE_CS1_BITS; ++ ++ if (ixp4xx_init_one(IXP4XX_IDE_BASE, IXP4XX_IDE_INT) == 0) ++ return 0; ++ ++ return -ENODEV; ++} ++ ++static __exit void ixp4xx_exit(void) ++{ ++ if (ixp4xx_host) ++ ata_host_set_remove(ixp4xx_host); ++} ++ ++MODULE_AUTHOR("Alessandro Zummo"); ++MODULE_DESCRIPTION("low-level driver for ixp4xx CF/ATA"); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION(DRV_VERSION); ++ ++module_init(ixp4xx_init); ++module_exit(ixp4xx_exit); +--- linux-ixp4xx.orig/drivers/scsi/libata-core.c 2006-02-24 18:13:55.000000000 +0100 ++++ linux-ixp4xx/drivers/scsi/libata-core.c 2006-02-24 18:16:46.000000000 +0100 +@@ -2513,8 +2513,8 @@ static void ata_dev_set_xfermode(struct + tf.nsect = dev->xfer_mode; + + if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) { +- printk(KERN_ERR "ata%u: failed to set xfermode, disabled\n", +- ap->id); ++ printk(KERN_ERR "ata%u: failed to set xfermode (0x%02x), disabled\n", ++ ap->id, dev->xfer_mode); + ata_port_disable(ap); + } + diff --git a/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-buttons.patch b/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-buttons.patch index b72c880259..09129ac56a 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-buttons.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-buttons.patch @@ -1,7 +1,7 @@ Index: linux-2.6.15/arch/arm/mach-ixp4xx/ds101-buttons.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/arch/arm/mach-ixp4xx/ds101-buttons.c 2006-02-16 20:04:47.000000000 +0100 ++++ linux-2.6.15/arch/arm/mach-ixp4xx/ds101-buttons.c 2006-02-23 08:40:28.000000000 +0100 @@ -0,0 +1,117 @@ +/* + * arch/arm/mach-ixp4xx/ds101-buttons.c @@ -47,7 +47,7 @@ Index: linux-2.6.15/arch/arm/mach-ixp4xx/ds101-buttons.c + if (powerb_irqcount > 1) + { + /* Make the power led flash */ -+ gpio_line_set(DS101_POWER_LED, DS101_GPIO_LOW); ++ gpio_line_set(DS101_POWER_LED, DS101_GPIO_HIGH); + ctrl_alt_del(); + } + return IRQ_HANDLED; diff --git a/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-doc.patch b/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-doc.patch new file mode 100644 index 0000000000..470c03ab56 --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-doc.patch @@ -0,0 +1,43 @@ +Index: linux-2.6.15/include/linux/mtd/doc2000.h +=================================================================== +--- linux-2.6.15.orig/include/linux/mtd/doc2000.h 2006-02-24 11:46:50.000000000 +0100 ++++ linux-2.6.15/include/linux/mtd/doc2000.h 2006-02-24 12:14:18.000000000 +0100 +@@ -73,14 +73,29 @@ + #define DoC_Mplus_Toggle 0x1046 + #define DoC_Mplus_DownloadStatus 0x1074 + #define DoC_Mplus_CtrlConfirm 0x1076 ++#ifdef CONFIG_MACH_DS101 ++#define DoC_Mplus_Power 0x1ffe ++#else + #define DoC_Mplus_Power 0x1fff ++#endif + + /* How to access the device? + * On ARM, it'll be mmap'd directly with 32-bit wide accesses. + * On PPC, it's mmap'd and 16-bit wide. ++ * On DS101 (an ARM device), some tricks are needed + * Others use readb/writeb + */ +-#if defined(__arm__) ++#ifdef CONFIG_MACH_DS101 ++#ifndef __ARMEB__ ++#define ReadDOC_(adr, reg) readw((unsigned long)(adr + reg) ^ 0x02) ++#define WriteDOC_(d, adr, reg) writew(d, (unsigned long)(adr + reg) ^ 0x02) ++#define DOC_IOREMAP_LEN 0x4000 ++#else ++#define ReadDOC_(adr, reg) swab16(readw((void __iomem *)(adr) + (reg))) ++#define WriteDOC_(d, adr, reg) writew(swab16(d), (void __iomem *)(adr) + (reg)) ++#define DOC_IOREMAP_LEN 0x4000 ++#endif ++#elif defined(__arm__) + #define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)))) + #define WriteDOC_(d, adr, reg) do{ *(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0) + #define DOC_IOREMAP_LEN 0x8000 +@@ -92,7 +107,6 @@ + #define ReadDOC_(adr, reg) readb((void __iomem *)(adr) + (reg)) + #define WriteDOC_(d, adr, reg) writeb(d, (void __iomem *)(adr) + (reg)) + #define DOC_IOREMAP_LEN 0x2000 +- + #endif + + #if defined(__i386__) || defined(__x86_64__) diff --git a/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-includes.patch b/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-includes.patch index e66f8692ca..3f94fab289 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-includes.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-includes.patch @@ -4,7 +4,7 @@ 3 files changed, 95 insertions(+) --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/ds101.h 2006-02-21 02:00:21.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/ds101.h 2006-02-23 18:09:24.000000000 +0100 @@ -0,0 +1,87 @@ +/* + * DS101 platform specific definitions @@ -93,18 +93,18 @@ + DS101_EXP_HOLD_T(1) | DS101_EXP_RECOVERY_T(1)| \ + DS101_EXP_SZ_16M | DS101_EXP_WR_EN | \ + DS101_EXP_BYTE_RD16 | DS101_EXP_CS_EN) ---- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/hardware.h 2006-02-21 01:57:32.000000000 +0100 -+++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/hardware.h 2006-02-21 02:00:21.000000000 +0100 -@@ -46,5 +46,6 @@ extern unsigned int processor_id; - #include "prpmc1100.h" +--- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/hardware.h 2006-02-23 18:09:14.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/hardware.h 2006-02-23 18:09:48.000000000 +0100 +@@ -47,5 +47,6 @@ extern unsigned int processor_id; #include "nslu2.h" #include "nas100d.h" + #include "dsmg600.h" +#include "ds101.h" #endif /* _ASM_ARCH_HARDWARE_H */ ---- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/irqs.h 2006-02-21 01:57:32.000000000 +0100 -+++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/irqs.h 2006-02-21 02:00:21.000000000 +0100 -@@ -108,5 +108,12 @@ +--- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/irqs.h 2006-02-23 18:09:14.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/irqs.h 2006-02-23 18:09:24.000000000 +0100 +@@ -108,6 +108,13 @@ #define IRQ_NAS100D_PCI_INTC IRQ_IXP4XX_GPIO9 #define IRQ_NAS100D_PCI_INTD IRQ_IXP4XX_GPIO8 #define IRQ_NAS100D_PCI_INTE IRQ_IXP4XX_GPIO7 @@ -116,4 +116,5 @@ +#define IRQ_DS101_PCI_INTB IRQ_IXP4XX_GPIO10 +#define IRQ_DS101_PCI_INTC IRQ_IXP4XX_GPIO9 - #endif + /* + * D-Link DSM-G600 board IRQs diff --git a/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-misc.patch b/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-misc.patch deleted file mode 100644 index 6f62a7debb..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-misc.patch +++ /dev/null @@ -1,33 +0,0 @@ - arch/arm/mach-ixp4xx/Kconfig | 8 ++++++++ - arch/arm/mach-ixp4xx/Makefile | 2 +- - 2 files changed, 9 insertions(+), 1 deletion(-) - -Index: linux-2.6.15/arch/arm/mach-ixp4xx/Kconfig -=================================================================== ---- linux-2.6.15.orig/arch/arm/mach-ixp4xx/Kconfig 2006-02-14 19:20:21.000000000 +0100 -+++ linux-2.6.15/arch/arm/mach-ixp4xx/Kconfig 2006-02-14 19:20:26.000000000 +0100 -@@ -86,6 +86,14 @@ - NAS 100d device. For more information on this platform, - see http://www.nslu2-linux.org/wiki/NAS100d/HomePage - -+config MACH_DS101 -+ bool -+ prompt "DS101" -+ help -+ Say 'Y' here if you want your kernel to support Synology's -+ DiskStation DS101(j) device. For more information on this -+ platform see http://www.nslu2-linux.org/wiki/DS101/HomePage -+ - # - # Avila and IXDP share the same source for now. Will change in future - # -Index: linux-2.6.15/arch/arm/mach-ixp4xx/Makefile -=================================================================== ---- linux-2.6.15.orig/arch/arm/mach-ixp4xx/Makefile 2006-02-14 19:20:21.000000000 +0100 -+++ linux-2.6.15/arch/arm/mach-ixp4xx/Makefile 2006-02-14 19:20:36.000000000 +0100 -@@ -10,4 +10,4 @@ - obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o - obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o - obj-$(CONFIG_MACH_NAS100D) += nas100d-pci.o nas100d-setup.o nas100d-power.o -- -+obj-$(CONFIG_MACH_DS101) += ds101-pci.o ds101-setup.o ds101-buttons.o diff --git a/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-setup.patch b/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-setup.patch index 8b3bbb07f7..af829b52d8 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-setup.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/97-ds101-setup.patch @@ -4,11 +4,13 @@ Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Rod Whitby <rod@whitby.id.au> Signed-off-by: OEyvind Repvik <oyvind@repvik.org> + arch/arm/mach-ixp4xx/Kconfig | 8 + + arch/arm/mach-ixp4xx/Makefile | 2 arch/arm/mach-ixp4xx/ds101-setup.c | 245 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 245 insertions(+) + 3 files changed, 254 insertions(+), 1 deletion(-) --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/arch/arm/mach-ixp4xx/ds101-setup.c 2006-02-21 02:00:16.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/ds101-setup.c 2006-02-23 18:08:40.000000000 +0100 @@ -0,0 +1,245 @@ +/* + * Synology DS101 board setup @@ -255,17 +257,11 @@ Signed-off-by: OEyvind Repvik <oyvind@repvik.org> + .timer = &ixp4xx_timer, + .init_machine = ds101_init, +MACHINE_END - arch/arm/mach-ixp4xx/Kconfig | 8 ++++++++ - arch/arm/mach-ixp4xx/Makefile | 2 +- - 2 files changed, 9 insertions(+), 1 deletion(-) - -Index: linux-2.6.15/arch/arm/mach-ixp4xx/Kconfig -=================================================================== ---- linux-2.6.15.orig/arch/arm/mach-ixp4xx/Kconfig 2006-02-14 19:20:21.000000000 +0100 -+++ linux-2.6.15/arch/arm/mach-ixp4xx/Kconfig 2006-02-14 19:20:26.000000000 +0100 -@@ -86,6 +86,14 @@ - NAS 100d device. For more information on this platform, - see http://www.nslu2-linux.org/wiki/NAS100d/HomePage +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/Kconfig 2006-02-23 18:08:38.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/Kconfig 2006-02-23 18:08:40.000000000 +0100 +@@ -94,6 +94,14 @@ config MACH_DSMG600 + DSM-G600 device. For more information on this platform, + see http://www.nslu2-linux.org/ +config MACH_DS101 + bool @@ -278,13 +274,11 @@ Index: linux-2.6.15/arch/arm/mach-ixp4xx/Kconfig # # Avila and IXDP share the same source for now. Will change in future # -Index: linux-2.6.15/arch/arm/mach-ixp4xx/Makefile -=================================================================== ---- linux-2.6.15.orig/arch/arm/mach-ixp4xx/Makefile 2006-02-14 19:20:21.000000000 +0100 -+++ linux-2.6.15/arch/arm/mach-ixp4xx/Makefile 2006-02-14 19:20:36.000000000 +0100 -@@ -10,4 +10,4 @@ - obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/Makefile 2006-02-23 18:08:38.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/Makefile 2006-02-23 18:09:09.000000000 +0100 +@@ -11,4 +11,4 @@ obj-$(CONFIG_MACH_GTWX5715) += gtwx5715- obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o obj-$(CONFIG_MACH_NAS100D) += nas100d-pci.o nas100d-setup.o nas100d-power.o + obj-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o dsmg600-setup.o - +obj-$(CONFIG_MACH_DS101) += ds101-pci.o ds101-setup.o ds101-buttons.o diff --git a/packages/linux/ixp4xx-kernel/2.6.16/defconfig b/packages/linux/ixp4xx-kernel/2.6.16/defconfig index 472a692a32..da2137aa3e 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/defconfig +++ b/packages/linux/ixp4xx-kernel/2.6.16/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc2 -# Thu Feb 9 23:00:47 2006 +# Linux kernel version: 2.6.16-rc4-git7 +# Fri Feb 24 22:40:39 2006 # CONFIG_ARM=y CONFIG_MMU=y @@ -12,7 +12,6 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -37,7 +36,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -# CONFIG_BASE_FULL is not set +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y @@ -47,7 +46,7 @@ CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 +CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set CONFIG_OBSOLETE_INTERMODULE=y @@ -124,6 +123,7 @@ CONFIG_ARCH_IXDP425=y CONFIG_ARCH_IXCDP1100=y # CONFIG_ARCH_PRPMC1100 is not set CONFIG_MACH_NAS100D=y +CONFIG_MACH_DSMG600=y CONFIG_MACH_DS101=y CONFIG_ARCH_IXDP4XX=y # CONFIG_MACH_GTWX5715 is not set @@ -220,6 +220,7 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=m CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -470,7 +471,8 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set -# CONFIG_NFTL is not set +CONFIG_NFTL=y +CONFIG_NFTL_RW=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set @@ -504,7 +506,6 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set # CONFIG_MTD_OBSOLETE_CHIPS is not set -# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access @@ -540,8 +541,9 @@ CONFIG_MTD_NAND=y CONFIG_MTD_NAND_VERIFY_WRITE=y CONFIG_MTD_NAND_IDS=y CONFIG_MTD_NAND_DISKONCHIP=y -# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set -CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x50000000 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH is not set # CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set # CONFIG_MTD_NAND_NANDSIM is not set @@ -669,10 +671,12 @@ CONFIG_SCSI_PATA_ARTOP=y # CONFIG_SCSI_PATA_LEGACY is not set # CONFIG_SCSI_PATA_MPIIX is not set # CONFIG_SCSI_PATA_NETCELL is not set +# CONFIG_SCSI_PATA_NS87410 is not set # CONFIG_SCSI_PATA_OLDPIIX is not set # CONFIG_SCSI_PATA_OPTI is not set -# CONFIG_SCSI_PATA_PCMCIA is not set +# CONFIG_SCSI_PATA_PDC_OLD is not set # CONFIG_SCSI_PATA_QDI is not set +# CONFIG_SCSI_PATA_RADISYS is not set # CONFIG_SCSI_PATA_RZ1000 is not set # CONFIG_SCSI_PATA_SC1200 is not set # CONFIG_SCSI_PATA_SERVERWORKS is not set @@ -681,6 +685,7 @@ CONFIG_SCSI_PATA_ARTOP=y # CONFIG_SCSI_PATA_TRIFLEX is not set # CONFIG_SCSI_PATA_VIA is not set # CONFIG_SCSI_PATA_WINBOND is not set +CONFIG_SCSI_PATA_IXP4XX=y # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set @@ -917,7 +922,7 @@ CONFIG_INPUT_IXP4XX_BEEPER=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -925,6 +930,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=1 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=16 @@ -957,7 +963,6 @@ CONFIG_IXP4XX_WATCHDOG=y # # CONFIG_USBPCWATCHDOG is not set # CONFIG_NVRAM is not set -# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -1023,9 +1028,7 @@ CONFIG_SENSORS_EEPROM=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -1040,7 +1043,7 @@ CONFIG_SENSORS_EEPROM=y # # Hardware Monitoring support # -CONFIG_HWMON=y +CONFIG_HWMON=m # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set @@ -1050,6 +1053,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set @@ -1077,6 +1081,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set +CONFIG_SENSORS_AD741X=m # CONFIG_HWMON_DEBUG_CHIP is not set # @@ -1277,7 +1282,7 @@ CONFIG_USB_EHCI_SPLIT_ISO=y CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set +CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set # diff --git a/packages/linux/ixp4xx-kernel/2.6.16/leds-class.patch b/packages/linux/ixp4xx-kernel/2.6.16/leds-class.patch index 9fbcae79b9..4eaab3070e 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/leds-class.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/leds-class.patch @@ -4,11 +4,33 @@ be controlled. Signed-off-by: Richard Purdie <rpurdie@rpsys.net> -Index: linux-2.6.15/drivers/leds/Kconfig -=================================================================== +--- + arch/arm/Kconfig | 2 + arch/arm/mach-pxa/corgi.c | 10 + + arch/arm/mach-pxa/spitz.c | 10 + + arch/arm/mach-pxa/tosa.c | 9 + + drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/ide/ide-disk.c | 17 ++ + drivers/leds/Kconfig | 70 +++++++++++ + drivers/leds/Makefile | 15 ++ + drivers/leds/led-class.c | 164 +++++++++++++++++++++++++++ + drivers/leds/led-core.c | 24 ++++ + drivers/leds/led-triggers.c | 236 ++++++++++++++++++++++++++++++++++++++++ + drivers/leds/leds-corgi.c | 121 ++++++++++++++++++++ + drivers/leds/leds-ixp4xx-gpio.c | 209 +++++++++++++++++++++++++++++++++++ + drivers/leds/leds-locomo.c | 91 +++++++++++++++ + drivers/leds/leds-spitz.c | 125 +++++++++++++++++++++ + drivers/leds/leds-tosa.c | 123 ++++++++++++++++++++ + drivers/leds/leds.h | 36 ++++++ + drivers/leds/ledtrig-timer.c | 205 ++++++++++++++++++++++++++++++++++ + drivers/mtd/nand/nand_base.c | 26 ++++ + include/linux/leds.h | 97 ++++++++++++++++ + 21 files changed, 1590 insertions(+), 3 deletions(-) + --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Kconfig 2006-01-29 16:02:38.000000000 +0000 -@@ -0,0 +1,18 @@ ++++ linux-ixp4xx/drivers/leds/Kconfig 2006-02-23 18:17:40.000000000 +0100 +@@ -0,0 +1,70 @@ + +menu "LED devices" + @@ -25,22 +47,81 @@ Index: linux-2.6.15/drivers/leds/Kconfig + This option enables the led sysfs class in /sys/class/leds. You'll + need this to do anything useful with LEDs. If unsure, say N. + ++config LEDS_TRIGGERS ++ bool "LED Trigger support" ++ depends NEW_LEDS ++ help ++ This option enables trigger support for the leds class. ++ These triggers allow kernel events to drive the LEDs and can ++ be configured via sysfs. If unsure, say Y. ++ ++config LEDS_CORGI ++ tristate "LED Support for the Sharp SL-C7x0 series" ++ depends LEDS_CLASS && PXA_SHARP_C7xx ++ help ++ This option enables support for the LEDs on Sharp Zaurus ++ SL-C7x0 series (C700, C750, C760, C860). ++ ++config LEDS_LOCOMO ++ tristate "LED Support for Locomo device" ++ depends LEDS_CLASS && SHARP_LOCOMO ++ help ++ This option enables support for the LEDs on Sharp Locomo. ++ Zaurus models SL-5500 and SL-5600. ++ ++config LEDS_SPITZ ++ tristate "LED Support for the Sharp SL-Cxx00 series" ++ depends LEDS_CLASS && PXA_SHARP_Cxx00 ++ help ++ This option enables support for the LEDs on Sharp Zaurus ++ SL-Cxx00 series (C1000, C3000, C3100). ++ ++config LEDS_IXP4XX ++ tristate "LED Support for GPIO connected LEDs on IXP4XX processors" ++ depends LEDS_CLASS && ARCH_IXP4XX ++ help ++ This option enables support for the LEDs connected to GPIO ++ outputs of the Intel IXP4XX processors. To be useful the ++ particular board must have LEDs and they must be connected ++ to the GPIO lines. If unsure, say Y. ++ ++config LEDS_TOSA ++ tristate "LED Support for the Sharp SL-6000 series" ++ depends LEDS_CLASS && PXA_SHARPSL ++ help ++ This option enables support for the LEDs on Sharp Zaurus ++ SL-6000 series. ++ ++config LEDS_TRIGGER_TIMER ++ tristate "LED Timer Trigger" ++ depends LEDS_TRIGGERS ++ help ++ This allows LEDs to be controlled by a programmable timer ++ via sysfs. If unsure, say Y. ++ +endmenu + -Index: linux-2.6.15/drivers/leds/Makefile -=================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Makefile 2006-01-29 16:02:38.000000000 +0000 -@@ -0,0 +1,4 @@ ++++ linux-ixp4xx/drivers/leds/Makefile 2006-02-23 18:17:40.000000000 +0100 +@@ -0,0 +1,15 @@ + +# LED Core +obj-$(CONFIG_NEW_LEDS) += led-core.o +obj-$(CONFIG_LEDS_CLASS) += led-class.o -Index: linux-2.6.15/include/linux/leds.h -=================================================================== ++obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o ++ ++# LED Platform Drivers ++obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o ++obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o ++obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o ++obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o ++obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o ++ ++# LED Triggers ++obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/include/linux/leds.h 2006-01-29 16:03:21.000000000 +0000 -@@ -0,0 +1,48 @@ ++++ linux-ixp4xx/include/linux/leds.h 2006-02-23 18:17:40.000000000 +0100 +@@ -0,0 +1,97 @@ +/* + * Driver model for leds and led triggers + * @@ -80,6 +161,11 @@ Index: linux-2.6.15/include/linux/leds.h + + /* Trigger data */ + char *default_trigger; ++#ifdef CONFIG_LEDS_TRIGGERS ++ struct led_trigger *trigger; ++ struct list_head trig_list; ++ void *trigger_data; ++#endif + + /* This protects the data in this structure */ + rwlock_t lock; @@ -89,11 +175,53 @@ Index: linux-2.6.15/include/linux/leds.h +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); -Index: linux-2.6.15/arch/arm/Kconfig -=================================================================== ---- linux-2.6.15.orig/arch/arm/Kconfig 2006-01-29 14:37:31.000000000 +0000 -+++ linux-2.6.15/arch/arm/Kconfig 2006-01-29 16:02:15.000000000 +0000 -@@ -774,6 +774,8 @@ ++ ++ ++/* ++ * LED Triggers ++ */ ++#ifdef CONFIG_LEDS_TRIGGERS ++ ++#define TRIG_NAME_MAX 50 ++ ++struct led_trigger { ++ /* Trigger Properties */ ++ const char *name; ++ void (*activate)(struct led_classdev *led_cdev); ++ void (*deactivate)(struct led_classdev *led_cdev); ++ ++ /* LEDs under control by this trigger (for simple triggers) */ ++ rwlock_t leddev_list_lock; ++ struct list_head led_cdevs; ++ ++ /* Link to next registered trigger */ ++ struct list_head next_trig; ++}; ++ ++/* Registration functions for complex triggers */ ++int led_trigger_register(struct led_trigger *trigger); ++void led_trigger_unregister(struct led_trigger *trigger); ++ ++/* Registration functions for simple triggers */ ++#define INIT_LED_TRIGGER(x) static struct led_trigger *x; ++#define INIT_LED_TRIGGER_GLOBAL(x) struct led_trigger *x; ++void led_trigger_register_simple(const char *name, struct led_trigger **trigger); ++void led_trigger_unregister_simple(struct led_trigger *trigger); ++void led_trigger_event(struct led_trigger *trigger, enum led_brightness event); ++ ++#else ++ ++/* Triggers aren't active - null macros */ ++#define INIT_LED_TRIGGER(x) ++#define INIT_LED_TRIGGER_GLOBAL(x) ++#define led_trigger_register_simple(x, y) do {} while(0) ++#define led_trigger_unregister_simple(x) do {} while(0) ++#define led_trigger_event(x, y) do {} while(0) ++ ++#endif +--- linux-ixp4xx.orig/arch/arm/Kconfig 2006-02-23 18:13:35.000000000 +0100 ++++ linux-ixp4xx/arch/arm/Kconfig 2006-02-23 18:17:40.000000000 +0100 +@@ -807,6 +807,8 @@ source "drivers/misc/Kconfig" source "drivers/mfd/Kconfig" @@ -102,23 +230,19 @@ Index: linux-2.6.15/arch/arm/Kconfig source "drivers/media/Kconfig" source "drivers/video/Kconfig" -Index: linux-2.6.15/drivers/Makefile -=================================================================== ---- linux-2.6.15.orig/drivers/Makefile 2006-01-29 14:42:52.000000000 +0000 -+++ linux-2.6.15/drivers/Makefile 2006-01-29 14:43:11.000000000 +0000 -@@ -68,6 +68,7 @@ +--- linux-ixp4xx.orig/drivers/Makefile 2006-02-23 18:13:35.000000000 +0100 ++++ linux-ixp4xx/drivers/Makefile 2006-02-23 18:17:40.000000000 +0100 +@@ -68,6 +68,7 @@ obj-$(CONFIG_MCA) += mca/ obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_MMC) += mmc/ +obj-$(CONFIG_NEW_LEDS) += leds/ obj-$(CONFIG_INFINIBAND) += infiniband/ - obj-$(CONFIG_SGI_IOC4) += sn/ + obj-$(CONFIG_SGI_SN) += sn/ obj-y += firmware/ -Index: linux-2.6.15/drivers/Kconfig -=================================================================== ---- linux-2.6.15.orig/drivers/Kconfig 2006-01-29 14:42:51.000000000 +0000 -+++ linux-2.6.15/drivers/Kconfig 2006-01-29 14:43:11.000000000 +0000 -@@ -64,6 +64,8 @@ +--- linux-ixp4xx.orig/drivers/Kconfig 2006-02-23 18:13:35.000000000 +0100 ++++ linux-ixp4xx/drivers/Kconfig 2006-02-23 18:17:40.000000000 +0100 +@@ -64,6 +64,8 @@ source "drivers/usb/Kconfig" source "drivers/mmc/Kconfig" @@ -127,11 +251,9 @@ Index: linux-2.6.15/drivers/Kconfig source "drivers/infiniband/Kconfig" source "drivers/sn/Kconfig" -Index: linux-2.6.15/drivers/leds/leds.h -=================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/leds.h 2006-01-29 16:02:38.000000000 +0000 -@@ -0,0 +1,26 @@ ++++ linux-ixp4xx/drivers/leds/leds.h 2006-02-23 18:17:40.000000000 +0100 +@@ -0,0 +1,36 @@ +/* + * LED Core + * @@ -158,11 +280,19 @@ Index: linux-2.6.15/drivers/leds/leds.h +extern rwlock_t leds_list_lock; +extern struct list_head leds_list; + -Index: linux-2.6.15/drivers/leds/led-class.c -=================================================================== ++#ifdef CONFIG_LEDS_TRIGGERS ++void led_trigger_set_default(struct led_classdev *led_cdev); ++void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger); ++#else ++#define led_trigger_set_default(x) do {} while(0) ++#define led_trigger_set(x, y) do {} while(0) ++#endif ++ ++ssize_t led_trigger_store(struct class_device *dev, const char *buf, size_t count); ++ssize_t led_trigger_show(struct class_device *dev, char *buf); --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/led-class.c 2006-01-29 16:02:38.000000000 +0000 -@@ -0,0 +1,150 @@ ++++ linux-ixp4xx/drivers/leds/led-class.c 2006-02-23 18:17:40.000000000 +0100 +@@ -0,0 +1,164 @@ +/* + * LED Class Core + * @@ -220,6 +350,9 @@ Index: linux-2.6.15/drivers/leds/led-class.c + +static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store); + ++#ifdef CONFIG_LEDS_TRIGGERS ++static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); ++#endif + +/** + * led_classdev_suspend - suspend an led_classdev. @@ -261,12 +394,17 @@ Index: linux-2.6.15/drivers/leds/led-class.c + + /* register the attributes */ + class_device_create_file(led_cdev->class_dev, &class_device_attr_brightness); ++#ifdef CONFIG_LEDS_TRIGGERS ++ class_device_create_file(led_cdev->class_dev, &class_device_attr_trigger); ++#endif + + /* add to the list of leds */ + write_lock(&leds_list_lock); + list_add_tail(&led_cdev->node, &leds_list); + write_unlock(&leds_list_lock); + ++ led_trigger_set_default(led_cdev); ++ + printk(KERN_INFO "Registered led device: %s\n", led_cdev->class_dev->class_id); + + return 0; @@ -281,6 +419,12 @@ Index: linux-2.6.15/drivers/leds/led-class.c +void led_classdev_unregister(struct led_classdev *led_cdev) +{ + class_device_remove_file(led_cdev->class_dev, &class_device_attr_brightness); ++#ifdef CONFIG_LEDS_TRIGGERS ++ class_device_remove_file(led_cdev->class_dev, &class_device_attr_trigger); ++#endif ++ ++ if (led_cdev->trigger) ++ led_trigger_set(led_cdev, NULL); + + class_device_unregister(led_cdev->class_dev); + @@ -313,10 +457,8 @@ Index: linux-2.6.15/drivers/leds/led-class.c +MODULE_AUTHOR("John Lenz, Richard Purdie"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("LED Class Interface"); -Index: linux-2.6.15/drivers/leds/led-core.c -=================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/led-core.c 2006-01-29 14:43:11.000000000 +0000 ++++ linux-ixp4xx/drivers/leds/led-core.c 2006-02-23 18:17:40.000000000 +0100 @@ -0,0 +1,24 @@ +/* + * LED Class Core @@ -342,171 +484,8 @@ Index: linux-2.6.15/drivers/leds/led-core.c +LIST_HEAD(leds_list); + +EXPORT_SYMBOL_GPL(leds_list); -Add support for LED triggers to the LED subsystem. "Triggers" are events -which change the state of an LED. Two kinds of trigger are available, -simple ones which can be added to exising code with minimum disruption -and complex ones for implementing new or more complex functionality. - -Signed-off-by: Richard Purdie <rpurdie@rpsys.net> - -Index: linux-2.6.15/drivers/leds/Kconfig -=================================================================== ---- linux-2.6.15.orig/drivers/leds/Kconfig 2006-01-29 15:52:16.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Kconfig 2006-01-29 16:02:35.000000000 +0000 -@@ -14,5 +14,13 @@ - This option enables the led sysfs class in /sys/class/leds. You'll - need this to do anything useful with LEDs. If unsure, say N. - -+config LEDS_TRIGGERS -+ bool "LED Trigger support" -+ depends NEW_LEDS -+ help -+ This option enables trigger support for the leds class. -+ These triggers allow kernel events to drive the LEDs and can -+ be configured via sysfs. If unsure, say Y. -+ - endmenu - -Index: linux-2.6.15/drivers/leds/Makefile -=================================================================== ---- linux-2.6.15.orig/drivers/leds/Makefile 2006-01-29 15:52:16.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Makefile 2006-01-29 16:02:35.000000000 +0000 -@@ -2,3 +2,4 @@ - # LED Core - obj-$(CONFIG_NEW_LEDS) += led-core.o - obj-$(CONFIG_LEDS_CLASS) += led-class.o -+obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o -Index: linux-2.6.15/drivers/leds/leds.h -=================================================================== ---- linux-2.6.15.orig/drivers/leds/leds.h 2006-01-29 15:54:46.000000000 +0000 -+++ linux-2.6.15/drivers/leds/leds.h 2006-01-29 15:55:02.000000000 +0000 -@@ -24,3 +24,13 @@ - extern rwlock_t leds_list_lock; - extern struct list_head leds_list; - -+#ifdef CONFIG_LEDS_TRIGGERS -+void led_trigger_set_default(struct led_classdev *led_cdev); -+void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger); -+#else -+#define led_trigger_set_default(x) do {} while(0) -+#define led_trigger_set(x, y) do {} while(0) -+#endif -+ -+ssize_t led_trigger_store(struct class_device *dev, const char *buf, size_t count); -+ssize_t led_trigger_show(struct class_device *dev, char *buf); -Index: linux-2.6.15/include/linux/leds.h -=================================================================== ---- linux-2.6.15.orig/include/linux/leds.h 2006-01-29 15:52:16.000000000 +0000 -+++ linux-2.6.15/include/linux/leds.h 2006-01-29 15:55:02.000000000 +0000 -@@ -38,6 +38,11 @@ - - /* Trigger data */ - char *default_trigger; -+#ifdef CONFIG_LEDS_TRIGGERS -+ struct led_trigger *trigger; -+ struct list_head trig_list; -+ void *trigger_data; -+#endif - - /* This protects the data in this structure */ - rwlock_t lock; -@@ -47,3 +52,47 @@ - extern void led_classdev_unregister(struct led_classdev *led_cdev); - extern void led_classdev_suspend(struct led_classdev *led_cdev); - extern void led_classdev_resume(struct led_classdev *led_cdev); -+ -+ -+/* -+ * LED Triggers -+ */ -+#ifdef CONFIG_LEDS_TRIGGERS -+ -+#define TRIG_NAME_MAX 50 -+ -+struct led_trigger { -+ /* Trigger Properties */ -+ const char *name; -+ void (*activate)(struct led_classdev *led_cdev); -+ void (*deactivate)(struct led_classdev *led_cdev); -+ -+ /* LEDs under control by this trigger (for simple triggers) */ -+ rwlock_t leddev_list_lock; -+ struct list_head led_cdevs; -+ -+ /* Link to next registered trigger */ -+ struct list_head next_trig; -+}; -+ -+/* Registration functions for complex triggers */ -+int led_trigger_register(struct led_trigger *trigger); -+void led_trigger_unregister(struct led_trigger *trigger); -+ -+/* Registration functions for simple triggers */ -+#define INIT_LED_TRIGGER(x) static struct led_trigger *x; -+#define INIT_LED_TRIGGER_GLOBAL(x) struct led_trigger *x; -+void led_trigger_register_simple(const char *name, struct led_trigger **trigger); -+void led_trigger_unregister_simple(struct led_trigger *trigger); -+void led_trigger_event(struct led_trigger *trigger, enum led_brightness event); -+ -+#else -+ -+/* Triggers aren't active - null macros */ -+#define INIT_LED_TRIGGER(x) -+#define INIT_LED_TRIGGER_GLOBAL(x) -+#define led_trigger_register_simple(x, y) do {} while(0) -+#define led_trigger_unregister_simple(x) do {} while(0) -+#define led_trigger_event(x, y) do {} while(0) -+ -+#endif -Index: linux-2.6.15/drivers/leds/led-class.c -=================================================================== ---- linux-2.6.15.orig/drivers/leds/led-class.c 2006-01-29 15:54:02.000000000 +0000 -+++ linux-2.6.15/drivers/leds/led-class.c 2006-01-29 15:55:02.000000000 +0000 -@@ -55,6 +55,9 @@ - - static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store); - -+#ifdef CONFIG_LEDS_TRIGGERS -+static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); -+#endif - - /** - * led_classdev_suspend - suspend an led_classdev. -@@ -96,12 +99,17 @@ - - /* register the attributes */ - class_device_create_file(led_cdev->class_dev, &class_device_attr_brightness); -+#ifdef CONFIG_LEDS_TRIGGERS -+ class_device_create_file(led_cdev->class_dev, &class_device_attr_trigger); -+#endif - - /* add to the list of leds */ - write_lock(&leds_list_lock); - list_add_tail(&led_cdev->node, &leds_list); - write_unlock(&leds_list_lock); - -+ led_trigger_set_default(led_cdev); -+ - printk(KERN_INFO "Registered led device: %s\n", led_cdev->class_dev->class_id); - - return 0; -@@ -116,6 +124,12 @@ - void led_classdev_unregister(struct led_classdev *led_cdev) - { - class_device_remove_file(led_cdev->class_dev, &class_device_attr_brightness); -+#ifdef CONFIG_LEDS_TRIGGERS -+ class_device_remove_file(led_cdev->class_dev, &class_device_attr_trigger); -+#endif -+ -+ if (led_cdev->trigger) -+ led_trigger_set(led_cdev, NULL); - - class_device_unregister(led_cdev->class_dev); - -Index: linux-2.6.15/drivers/leds/led-triggers.c -=================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/led-triggers.c 2006-01-29 15:56:15.000000000 +0000 ++++ linux-ixp4xx/drivers/leds/led-triggers.c 2006-02-23 18:17:40.000000000 +0100 @@ -0,0 +1,236 @@ +/* + * LED Triggers Core @@ -744,44 +723,8 @@ Index: linux-2.6.15/drivers/leds/led-triggers.c +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("LED Triggers Core"); + -Add an example of a complex LED trigger in the form of a generic timer -which triggers the LED its attached to at a user specified frequency -and duty cycle. - -Signed-off-by: Richard Purdie <rpurdie@rpsys.net> - -Index: linux-2.6.15/drivers/leds/Kconfig -=================================================================== ---- linux-2.6.15.orig/drivers/leds/Kconfig 2006-01-29 16:13:48.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Kconfig 2006-01-29 20:32:16.000000000 +0000 -@@ -22,5 +22,12 @@ - These triggers allow kernel events to drive the LEDs and can - be configured via sysfs. If unsure, say Y. - -+config LEDS_TRIGGER_TIMER -+ tristate "LED Timer Trigger" -+ depends LEDS_TRIGGERS -+ help -+ This allows LEDs to be controlled by a programmable timer -+ via sysfs. If unsure, say Y. -+ - endmenu - -Index: linux-2.6.15/drivers/leds/Makefile -=================================================================== ---- linux-2.6.15.orig/drivers/leds/Makefile 2006-01-29 16:13:48.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Makefile 2006-01-29 20:32:16.000000000 +0000 -@@ -3,3 +3,6 @@ - obj-$(CONFIG_NEW_LEDS) += led-core.o - obj-$(CONFIG_LEDS_CLASS) += led-class.o - obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o -+ -+# LED Triggers -+obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o -Index: linux-2.6.15/drivers/leds/ledtrig-timer.c -=================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/ledtrig-timer.c 2006-01-29 17:40:11.000000000 +0000 ++++ linux-ixp4xx/drivers/leds/ledtrig-timer.c 2006-02-23 18:17:40.000000000 +0100 @@ -0,0 +1,205 @@ +/* + * LED Kernel Timer Trigger @@ -891,7 +834,7 @@ Index: linux-2.6.15/drivers/leds/ledtrig-timer.c + timer_data = led_cdev->trigger_data; + ret = led_timer_setdata(led_cdev, state, timer_data->frequency); + if (!ret) -+ ret = after - buf; ++ ret = after - buf; + write_unlock(&led_cdev->lock); + } + @@ -925,7 +868,7 @@ Index: linux-2.6.15/drivers/leds/ledtrig-timer.c + timer_data = led_cdev->trigger_data; + ret = led_timer_setdata(led_cdev, timer_data->duty, state); + if (!ret) -+ ret = after - buf; ++ ret = after - buf; + write_unlock(&led_cdev->lock); + } + @@ -988,16 +931,9 @@ Index: linux-2.6.15/drivers/leds/ledtrig-timer.c +MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); +MODULE_DESCRIPTION("Timer LED trigger"); +MODULE_LICENSE("GPL"); -Adds LED drivers for LEDs found on the Sharp Zaurus c7x0 (corgi, -shepherd, husky) and cxx00 (akita, spitz, borzoi) models. - -Signed-off-by: Richard Purdie <rpurdie@rpsys.net> - -Index: linux-2.6.15/arch/arm/mach-pxa/corgi.c -=================================================================== ---- linux-2.6.15.orig/arch/arm/mach-pxa/corgi.c 2006-01-29 16:02:30.000000000 +0000 -+++ linux-2.6.15/arch/arm/mach-pxa/corgi.c 2006-01-29 16:11:47.000000000 +0000 -@@ -165,6 +165,15 @@ +--- linux-ixp4xx.orig/arch/arm/mach-pxa/corgi.c 2006-02-23 18:13:35.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-pxa/corgi.c 2006-02-23 18:17:40.000000000 +0100 +@@ -165,6 +165,15 @@ static struct platform_device corgikbd_d /* @@ -1013,7 +949,7 @@ Index: linux-2.6.15/arch/arm/mach-pxa/corgi.c * Corgi Touch Screen Device */ static struct resource corgits_resources[] = { -@@ -298,6 +307,7 @@ +@@ -298,6 +307,7 @@ static struct platform_device *devices[] &corgikbd_device, &corgibl_device, &corgits_device, @@ -1021,11 +957,9 @@ Index: linux-2.6.15/arch/arm/mach-pxa/corgi.c }; static void __init corgi_init(void) -Index: linux-2.6.15/arch/arm/mach-pxa/spitz.c -=================================================================== ---- linux-2.6.15.orig/arch/arm/mach-pxa/spitz.c 2006-01-29 16:02:30.000000000 +0000 -+++ linux-2.6.15/arch/arm/mach-pxa/spitz.c 2006-01-29 16:11:48.000000000 +0000 -@@ -243,6 +243,15 @@ +--- linux-ixp4xx.orig/arch/arm/mach-pxa/spitz.c 2006-02-23 18:13:35.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-pxa/spitz.c 2006-02-23 18:17:40.000000000 +0100 +@@ -243,6 +243,15 @@ static struct platform_device spitzkbd_d /* @@ -1041,7 +975,7 @@ Index: linux-2.6.15/arch/arm/mach-pxa/spitz.c * Spitz Touch Screen Device */ static struct resource spitzts_resources[] = { -@@ -419,6 +428,7 @@ +@@ -419,6 +428,7 @@ static struct platform_device *devices[] &spitzkbd_device, &spitzts_device, &spitzbl_device, @@ -1049,49 +983,8 @@ Index: linux-2.6.15/arch/arm/mach-pxa/spitz.c }; static void __init common_init(void) -Index: linux-2.6.15/drivers/leds/Kconfig -=================================================================== ---- linux-2.6.15.orig/drivers/leds/Kconfig 2006-01-29 16:04:20.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Kconfig 2006-01-29 16:11:54.000000000 +0000 -@@ -22,6 +22,20 @@ - These triggers allow kernel events to drive the LEDs and can - be configured via sysfs. If unsure, say Y. - -+config LEDS_CORGI -+ tristate "LED Support for the Sharp SL-C7x0 series" -+ depends LEDS_CLASS && PXA_SHARP_C7xx -+ help -+ This option enables support for the LEDs on Sharp Zaurus -+ SL-C7x0 series (C700, C750, C760, C860). -+ -+config LEDS_SPITZ -+ tristate "LED Support for the Sharp SL-Cxx00 series" -+ depends LEDS_CLASS && PXA_SHARP_Cxx00 -+ help -+ This option enables support for the LEDs on Sharp Zaurus -+ SL-Cxx00 series (C1000, C3000, C3100). -+ - config LEDS_TRIGGER_TIMER - tristate "LED Timer Trigger" - depends LEDS_TRIGGERS -Index: linux-2.6.15/drivers/leds/Makefile -=================================================================== ---- linux-2.6.15.orig/drivers/leds/Makefile 2006-01-29 16:04:20.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Makefile 2006-01-29 16:11:54.000000000 +0000 -@@ -4,5 +4,9 @@ - obj-$(CONFIG_LEDS_CLASS) += led-class.o - obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o - -+# LED Platform Drivers -+obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o -+obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o -+ - # LED Triggers - obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o -Index: linux-2.6.15/drivers/leds/leds-corgi.c -=================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/leds-corgi.c 2006-01-29 16:08:42.000000000 +0000 ++++ linux-ixp4xx/drivers/leds/leds-corgi.c 2006-02-23 18:17:40.000000000 +0100 @@ -0,0 +1,121 @@ +/* + * LED Triggers Core @@ -1214,10 +1107,8 @@ Index: linux-2.6.15/drivers/leds/leds-corgi.c +MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); +MODULE_DESCRIPTION("Corgi LED driver"); +MODULE_LICENSE("GPL"); -Index: linux-2.6.15/drivers/leds/leds-spitz.c -=================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/leds-spitz.c 2006-01-29 16:08:09.000000000 +0000 ++++ linux-ixp4xx/drivers/leds/leds-spitz.c 2006-02-23 18:17:40.000000000 +0100 @@ -0,0 +1,125 @@ +/* + * LED Triggers Core @@ -1344,45 +1235,8 @@ Index: linux-2.6.15/drivers/leds/leds-spitz.c +MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); +MODULE_DESCRIPTION("Spitz LED driver"); +MODULE_LICENSE("GPL"); -Adds an LED driver for LEDs exported by the Sharp LOCOMO chip as found on -some models of Sharp Zaurus. - -Signed-off-by: Richard Purdie <rpurdie@rpsys.net> - -Index: linux-2.6.15/drivers/leds/Kconfig -=================================================================== ---- linux-2.6.15.orig/drivers/leds/Kconfig 2006-01-29 16:04:22.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Kconfig 2006-01-29 16:04:23.000000000 +0000 -@@ -29,6 +29,13 @@ - This option enables support for the LEDs on Sharp Zaurus - SL-C7x0 series (C700, C750, C760, C860). - -+config LEDS_LOCOMO -+ tristate "LED Support for Locomo device" -+ depends LEDS_CLASS && SHARP_LOCOMO -+ help -+ This option enables support for the LEDs on Sharp Locomo. -+ Zaurus models SL-5500 and SL-5600. -+ - config LEDS_SPITZ - tristate "LED Support for the Sharp SL-Cxx00 series" - depends LEDS_CLASS && PXA_SHARP_Cxx00 -Index: linux-2.6.15/drivers/leds/Makefile -=================================================================== ---- linux-2.6.15.orig/drivers/leds/Makefile 2006-01-29 16:04:22.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Makefile 2006-01-29 16:04:23.000000000 +0000 -@@ -6,6 +6,7 @@ - - # LED Platform Drivers - obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o -+obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o - obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o - - # LED Triggers -Index: linux-2.6.15/drivers/leds/leds-locomo.c -=================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/leds-locomo.c 2006-01-29 16:09:46.000000000 +0000 ++++ linux-ixp4xx/drivers/leds/leds-locomo.c 2006-02-23 18:17:40.000000000 +0100 @@ -0,0 +1,91 @@ +/* + * linux/drivers/leds/locomo.c @@ -1475,47 +1329,8 @@ Index: linux-2.6.15/drivers/leds/leds-locomo.c +MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>"); +MODULE_DESCRIPTION("Locomo LED driver"); +MODULE_LICENSE("GPL"); -From: John Bowler <jbowler@acm.org> - -NEW_LEDS support for ixp4xx boards where LEDs are connected -to the GPIO lines. - -This includes a new generic ixp4xx driver (leds-ixp4xx-gpio.c -name "IXP4XX-GPIO-LED") - -Signed-off-by: John Bowler <jbowler@acm.org> -Signed-off-by: Richard Purdie <rpurdie@rpsys.net> - ---- linux-2.6.15/drivers/leds/Kconfig 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Kconfig 1970-01-01 00:00:00.000000000 +0000 -@@ -43,6 +43,15 @@ config LEDS_SPITZ - This option enables support for the LEDs on Sharp Zaurus - SL-Cxx00 series (C1000, C3000, C3100). - -+config LEDS_IXP4XX -+ tristate "LED Support for GPIO connected LEDs on IXP4XX processors" -+ depends LEDS_CLASS && ARCH_IXP4XX -+ help -+ This option enables support for the LEDs connected to GPIO -+ outputs of the Intel IXP4XX processors. To be useful the -+ particular board must have LEDs and they must be connected -+ to the GPIO lines. If unsure, say Y. -+ - config LEDS_TRIGGER_TIMER - tristate "LED Timer Trigger" - depends LEDS_TRIGGERS ---- linux-2.6.15/drivers/leds/Makefile 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Makefile 1970-01-01 00:00:00.000000000 +0000 -@@ -8,6 +8,7 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-trig - obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o - obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o - obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o -+obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o - - # LED Triggers - obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o ---- linux-2.6.15/drivers/leds/leds-ixp4xx-gpio.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/leds-ixp4xx-gpio.c 1970-01-01 00:00:00.000000000 +0000 +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/drivers/leds/leds-ixp4xx-gpio.c 2006-02-23 18:17:40.000000000 +0100 @@ -0,0 +1,209 @@ +/* + * IXP4XX GPIO driver LED driver @@ -1679,7 +1494,7 @@ Signed-off-by: Richard Purdie <rpurdie@rpsys.net> + ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 0; + + ixp4xxgpioled_devices[gpio_pin].ancestor.flags = 0; -+ ++ + ixp4xxgpioled_devices[gpio_pin].ancestor.brightness_set = + ixp4xxgpioled_brightness_set; + @@ -1726,47 +1541,8 @@ Signed-off-by: Richard Purdie <rpurdie@rpsys.net> +MODULE_AUTHOR("John Bowler <jbowler@acm.org>"); +MODULE_DESCRIPTION("IXP4XX GPIO LED driver"); +MODULE_LICENSE("MIT"); -From: Dirk Opfer <dirk@opfer-online.de> - -Adds LED drivers for LEDs found on the Sharp Zaurus c6000 model (tosa). - -Signed-off-by: Dirk Opfer <dirk@opfer-online.de> -Signed-off-by: Richard Purdie <rpurdie@rpsys.net> - -Index: linux-2.6.15/drivers/leds/Kconfig -=================================================================== ---- linux-2.6.15.orig/drivers/leds/Kconfig 2006-01-30 00:25:28.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Kconfig 2006-01-30 00:25:52.000000000 +0000 -@@ -52,6 +52,13 @@ - particular board must have LEDs and they must be connected - to the GPIO lines. If unsure, say Y. - -+config LEDS_TOSA -+ tristate "LED Support for the Sharp SL-6000 series" -+ depends LEDS_CLASS && PXA_SHARPSL -+ help -+ This option enables support for the LEDs on Sharp Zaurus -+ SL-6000 series. -+ - config LEDS_TRIGGER_TIMER - tristate "LED Timer Trigger" - depends LEDS_TRIGGERS -Index: linux-2.6.15/drivers/leds/Makefile -=================================================================== ---- linux-2.6.15.orig/drivers/leds/Makefile 2006-01-30 00:25:28.000000000 +0000 -+++ linux-2.6.15/drivers/leds/Makefile 2006-01-30 00:26:48.000000000 +0000 -@@ -9,6 +9,7 @@ - obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o - obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o - obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o -+obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o - - # LED Triggers - obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o -Index: linux-2.6.15/drivers/leds/leds-tosa.c -=================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/leds/leds-tosa.c 2006-01-30 00:28:15.000000000 +0000 ++++ linux-ixp4xx/drivers/leds/leds-tosa.c 2006-02-23 18:17:40.000000000 +0100 @@ -0,0 +1,123 @@ +/* + * LED Triggers Core @@ -1891,11 +1667,9 @@ Index: linux-2.6.15/drivers/leds/leds-tosa.c +MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>"); +MODULE_DESCRIPTION("Tosa LED driver"); +MODULE_LICENSE("GPL"); -Index: linux-2.6.15/arch/arm/mach-pxa/tosa.c -=================================================================== ---- linux-2.6.15.orig/arch/arm/mach-pxa/tosa.c 2006-01-03 03:21:10.000000000 +0000 -+++ linux-2.6.15/arch/arm/mach-pxa/tosa.c 2006-01-30 00:29:25.000000000 +0000 -@@ -252,10 +252,19 @@ +--- linux-ixp4xx.orig/arch/arm/mach-pxa/tosa.c 2006-02-23 18:13:35.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-pxa/tosa.c 2006-02-23 18:17:40.000000000 +0100 +@@ -252,10 +252,19 @@ static struct platform_device tosakbd_de .id = -1, }; @@ -1906,7 +1680,7 @@ Index: linux-2.6.15/arch/arm/mach-pxa/tosa.c + .name = "tosa-led", + .id = -1, +}; -+ ++ static struct platform_device *devices[] __initdata = { &tosascoop_device, &tosascoop_jc_device, @@ -1915,14 +1689,8 @@ Index: linux-2.6.15/arch/arm/mach-pxa/tosa.c }; static void __init tosa_init(void) -Add an LED trigger for IDE disk activity to the IDE subsystem. - -Signed-off-by: Richard Purdie <rpurdie@rpsys.net> - -Index: linux-2.6.15/drivers/ide/ide-disk.c -=================================================================== ---- linux-2.6.15.orig/drivers/ide/ide-disk.c 2006-02-04 13:35:37.000000000 +0000 -+++ linux-2.6.15/drivers/ide/ide-disk.c 2006-02-04 15:17:18.000000000 +0000 +--- linux-ixp4xx.orig/drivers/ide/ide-disk.c 2006-02-23 18:13:35.000000000 +0100 ++++ linux-ixp4xx/drivers/ide/ide-disk.c 2006-02-23 18:17:40.000000000 +0100 @@ -60,6 +60,7 @@ #include <linux/genhd.h> #include <linux/slab.h> @@ -1931,7 +1699,7 @@ Index: linux-2.6.15/drivers/ide/ide-disk.c #define _IDE_DISK -@@ -80,6 +81,8 @@ +@@ -80,6 +81,8 @@ struct ide_disk_obj { static DECLARE_MUTEX(idedisk_ref_sem); @@ -1940,7 +1708,7 @@ Index: linux-2.6.15/drivers/ide/ide-disk.c #define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref) #define ide_disk_g(disk) \ -@@ -311,10 +314,12 @@ +@@ -312,10 +315,12 @@ static ide_startstop_t ide_do_rw_disk (i if (!blk_fs_request(rq)) { blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command"); @@ -1953,8 +1721,8 @@ Index: linux-2.6.15/drivers/ide/ide-disk.c + pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", drive->name, rq_data_dir(rq) == READ ? "read" : "writ", - block, rq->nr_sectors, (unsigned long)rq->buffer); -@@ -325,6 +330,12 @@ + (unsigned long long)block, rq->nr_sectors, +@@ -327,6 +332,12 @@ static ide_startstop_t ide_do_rw_disk (i return __ide_do_rw_disk(drive, rq, block); } @@ -1967,7 +1735,7 @@ Index: linux-2.6.15/drivers/ide/ide-disk.c /* * Queries for true maximum capacity of the drive. * Returns maximum LBA address (> 0) of the drive, 0 if failed. -@@ -1097,7 +1108,7 @@ +@@ -1063,7 +1074,7 @@ static ide_driver_t idedisk_driver = { .media = ide_disk, .supports_dsc_overlap = 0, .do_request = ide_do_rw_disk, @@ -1976,7 +1744,7 @@ Index: linux-2.6.15/drivers/ide/ide-disk.c .error = __ide_error, .abort = __ide_abort, .proc = idedisk_proc, -@@ -1259,11 +1270,13 @@ +@@ -1236,11 +1247,13 @@ failed: static void __exit idedisk_exit (void) { @@ -1990,10 +1758,8 @@ Index: linux-2.6.15/drivers/ide/ide-disk.c return driver_register(&idedisk_driver.gen_driver); } -Index: linux-2.6.15/drivers/mtd/nand/nand_base.c -=================================================================== ---- linux-2.6.15.orig/drivers/mtd/nand/nand_base.c 2006-01-29 14:37:20.000000000 +0000 -+++ linux-2.6.15/drivers/mtd/nand/nand_base.c 2006-01-29 15:25:11.000000000 +0000 +--- linux-ixp4xx.orig/drivers/mtd/nand/nand_base.c 2006-02-23 18:13:35.000000000 +0100 ++++ linux-ixp4xx/drivers/mtd/nand/nand_base.c 2006-02-23 18:17:40.000000000 +0100 @@ -80,6 +80,7 @@ #include <linux/mtd/compatmac.h> #include <linux/interrupt.h> @@ -2002,7 +1768,7 @@ Index: linux-2.6.15/drivers/mtd/nand/nand_base.c #include <asm/io.h> #ifdef CONFIG_MTD_PARTITIONS -@@ -515,6 +516,8 @@ +@@ -515,6 +516,8 @@ static int nand_block_checkbad (struct m return nand_isbad_bbt (mtd, ofs, allowbbt); } @@ -2011,7 +1777,7 @@ Index: linux-2.6.15/drivers/mtd/nand/nand_base.c /* * Wait for the ready pin, after a command * The timeout is catched later. -@@ -524,12 +527,14 @@ +@@ -524,12 +527,14 @@ static void nand_wait_ready(struct mtd_i struct nand_chip *this = mtd->priv; unsigned long timeo = jiffies + 2; @@ -2027,7 +1793,7 @@ Index: linux-2.6.15/drivers/mtd/nand/nand_base.c } /** -@@ -817,6 +822,8 @@ +@@ -817,6 +822,8 @@ static int nand_wait(struct mtd_info *mt else timeo += (HZ * 20) / 1000; @@ -2036,16 +1802,16 @@ Index: linux-2.6.15/drivers/mtd/nand/nand_base.c /* Apply this short delay always to ensure that we do wait tWB in * any case on any machine. */ ndelay (100); -@@ -840,6 +847,8 @@ +@@ -840,6 +847,8 @@ static int nand_wait(struct mtd_info *mt } cond_resched(); } + led_trigger_event(nand_led_trigger, LED_OFF); -+ ++ status = (int) this->read_byte(mtd); return status; } -@@ -2724,6 +2733,21 @@ +@@ -2724,6 +2733,21 @@ void nand_release (struct mtd_info *mtd) EXPORT_SYMBOL_GPL (nand_scan); EXPORT_SYMBOL_GPL (nand_release); @@ -2055,7 +1821,7 @@ Index: linux-2.6.15/drivers/mtd/nand/nand_base.c + led_trigger_register_simple("nand-disk", &nand_led_trigger); + return 0; +} -+ ++ +static void nand_base_exit(void) +{ + led_trigger_unregister_simple(nand_led_trigger); diff --git a/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide1 b/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide2 index 7e2561c0f9..ea23ff47d3 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide1 +++ b/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide2 @@ -344,7 +344,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 +module_exit(pata_generic_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/ata_piix.c linux-2.6.16-rc4/drivers/scsi/ata_piix.c --- linux.vanilla-2.6.16-rc4/drivers/scsi/ata_piix.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/ata_piix.c 2006-02-16 15:35:51.000000000 +0000 ++++ linux-2.6.16-rc4/drivers/scsi/ata_piix.c 2006-02-20 20:06:17.000000000 +0000 @@ -91,9 +91,10 @@ #include <linux/device.h> #include <scsi/scsi_host.h> @@ -353,7 +353,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 #define DRV_NAME "ata_piix" -#define DRV_VERSION "1.05" -+#define DRV_VERSION "1.05-ac1" ++#define DRV_VERSION "1.05-ac7" enum { PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ @@ -497,7 +497,14 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, -@@ -259,13 +356,9 @@ +@@ -253,47 +350,39 @@ + }; + + static struct ata_port_info piix_port_info[] = { +- /* ich5_pata */ ++ /* ich5_pata: 0*/ + { + .sht = &piix_sht, .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | PIIX_FLAG_CHECKINTR, .pio_mask = 0x1f, /* pio0-4 */ @@ -506,13 +513,28 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 -#else - .mwdma_mask = 0x00, /* mwdma broken */ -#endif - .udma_mask = 0x3f, /* udma0-5 */ +- .udma_mask = 0x3f, /* udma0-5 */ - .port_ops = &piix_pata_ops, ++ .udma_mask = ATA_UDMA6, + .port_ops = &ich_pata_ops, }, - /* ich5_sata */ -@@ -284,11 +377,7 @@ +- /* ich5_sata */ ++ /* ich5_sata: 1 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | + PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ +- .udma_mask = 0x7f, /* udma0-6 */ ++ .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + +- /* piix4_pata */ ++ /* piix4_pata: 2 */ + { .sht = &piix_sht, .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ @@ -524,62 +546,86 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 .udma_mask = ATA_UDMA_MASK_40C, .port_ops = &piix_pata_ops, }, -@@ -316,6 +405,116 @@ - .udma_mask = 0x7f, /* udma0-6 */ + +- /* ich6_sata */ ++ /* ich6_sata: 3 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | +@@ -301,11 +390,11 @@ + ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ +- .udma_mask = 0x7f, /* udma0-6 */ ++ .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + +- /* ich6_sata_ahci */ ++ /* ich6_sata_ahci: 4 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | +@@ -313,9 +402,119 @@ + ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ +- .udma_mask = 0x7f, /* udma0-6 */ ++ .udma_mask = ATA_UDMA6, .port_ops = &piix_sata_ops, }, + -+ /* ich0_pata */ ++ /* ich0_pata: 5 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio 0-4 */ + .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ -+ .udma_mask = 0x07, /* UDMA33 only */ ++ .udma_mask = ATA_UDMA4, + .port_ops = &ich_pata_ops, + }, + -+ /* ich2_pata */ ++ /* ich2_pata: 6 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio 0-4 */ + .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ -+ .udma_mask = 0x1f, /* UDMA100 */ ++ .udma_mask = ATA_UDMA5, + .port_ops = &ich_pata_ops, + }, + -+ /* ich3_pata */ ++ /* ich3_pata: 7 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio 0-4 */ + .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ -+ .udma_mask = 0x1f, /* UDMA100 */ ++ .udma_mask = ATA_UDMA5, + .port_ops = &ich_pata_ops, + }, + -+ /* ich4_pata */ ++ /* ich4_pata: 8 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio 0-4 */ + .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x1f, /* UDMA100 */ ++ .udma_mask = ATA_UDMA5, + .port_ops = &ich_pata_ops, + }, + -+ /* cich_pata */ ++ /* cich_pata: 9 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio 0-4 */ + .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x1f, /* UDMA100 */ ++ .udma_mask = ATA_UDMA5, + .port_ops = &ich_pata_ops, + }, + -+ /* piix3_pata */ ++ /* piix3_pata: 10 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, @@ -589,53 +635,53 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + .port_ops = &piix_pata_ops, + }, + -+ /* esb_pata */ ++ /* esb_pata: 11 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio 0-4 */ + .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x1f, /* UDMA100 */ ++ .udma_mask = ATA_UDMA5, + .port_ops = &piix_pata_ops, + }, + -+ /* ich_pata */ ++ /* ich_pata: 12 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio 0-4 */ + .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x07, /* UDMA66 */ ++ .udma_mask = ATA_UDMA4, /* UDMA66 */ + .port_ops = &ich_pata_ops, + }, + -+ /* ich6_pata */ ++ /* ich6_pata: 13 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio 0-4 */ + .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x3f, /* UDMA133 */ ++ .udma_mask = ATA_UDMA6, /* UDMA133 */ + .port_ops = &ich_pata_ops, + }, + -+ /* ich7_pata */ ++ /* ich7_pata: 14 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio 0-4 */ + .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x3f, /* UDMA133 */ ++ .udma_mask = ATA_UDMA6, + .port_ops = &ich_pata_ops, + }, + -+ /* esb2_pata */ ++ /* esb2_pata: 15 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio 0-4 */ + .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = 0x1f, /* UDMA100 -- CHECKME --*/ ++ .udma_mask = ATA_UDMA5, + .port_ops = &ich_pata_ops, + }, }; @@ -1000,7 +1046,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/Kconfig linux-2.6.16-rc4/drivers/scsi/Kconfig --- linux.vanilla-2.6.16-rc4/drivers/scsi/Kconfig 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/Kconfig 2006-02-17 18:22:18.000000000 +0000 ++++ linux-2.6.16-rc4/drivers/scsi/Kconfig 2006-02-20 17:27:24.000000000 +0000 @@ -599,6 +599,316 @@ depends on IDE=y && !BLK_DEV_IDE_SATA && (SCSI_SATA_AHCI || SCSI_ATA_PIIX) default y @@ -1213,7 +1259,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + +config SCSI_PATA_PCMCIA + tristate "PCMCIA PATA support (Raving Lunatic)" -+ depends on SCSI_SATA ++ depends on SCSI_SATA && PCMCIA + help + This option enables support for PCMCIA ATA interfaces, including + compact flash card adapters via the new ATA layer. @@ -1320,7 +1366,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/libata-core.c linux-2.6.16-rc4/drivers/scsi/libata-core.c --- linux.vanilla-2.6.16-rc4/drivers/scsi/libata-core.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/libata-core.c 2006-02-20 11:28:03.000000000 +0000 ++++ linux-2.6.16-rc4/drivers/scsi/libata-core.c 2006-02-23 13:37:47.358092040 +0000 @@ -68,9 +68,10 @@ static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); static void ata_set_mode(struct ata_port *ap); @@ -1333,6 +1379,15 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 u8 *xfer_mode_out, unsigned int *xfer_shift_out); static void __ata_qc_complete(struct ata_queued_cmd *qc); +@@ -78,7 +79,7 @@ + static unsigned int ata_unique_id = 1; + static struct workqueue_struct *ata_wq; + +-int atapi_enabled = 0; ++int atapi_enabled = 1; + module_param(atapi_enabled, int, 0444); + MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); + @@ -1205,6 +1206,48 @@ return 0; } @@ -1405,7 +1460,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 } /* ATAPI-specific feature tests */ -@@ -1485,10 +1535,23 @@ +@@ -1485,10 +1535,24 @@ ap->ops->phy_reset(ap); if (ap->flags & ATA_FLAG_PORT_DISABLED) goto err_out; @@ -1422,7 +1477,8 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + + /* Set up the controller on this port for PIO 0. We must not + send the drive speed setting commands at this point */ -+ ap->ops->set_piomode(ap, adev); ++ if (ap->ops->set_piomode) ++ ap->ops->set_piomode(ap, adev); + ata_dev_identify(ap, i); - if (ata_dev_present(&ap->device[i])) { @@ -1430,7 +1486,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 found = 1; ata_dev_config(ap,i); } -@@ -1497,7 +1560,11 @@ +@@ -1497,7 +1561,11 @@ if ((!found) || (ap->flags & ATA_FLAG_PORT_DISABLED)) goto err_out_disable; @@ -1443,7 +1499,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 if (ap->flags & ATA_FLAG_PORT_DISABLED) goto err_out_disable; -@@ -1612,6 +1679,23 @@ +@@ -1612,6 +1680,23 @@ } /** @@ -1467,7 +1523,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 * ata_port_disable - Disable port. * @ap: Port to be disabled. * -@@ -1824,16 +1908,19 @@ +@@ -1824,16 +1909,19 @@ ap->id, dev->devno, xfer_mode_str[idx]); } @@ -1491,7 +1547,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 return -1; } -@@ -1843,34 +1930,24 @@ +@@ -1843,34 +1931,24 @@ DPRINTK("base 0x%x xfer_mode 0x%x mask 0x%x x %d\n", (int)base, (int)xfer_mode, mask, x); @@ -1539,7 +1595,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 } } -@@ -1886,32 +1963,64 @@ +@@ -1886,32 +1964,64 @@ */ static void ata_set_mode(struct ata_port *ap) { @@ -1565,14 +1621,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + /* Compute the timings first so that when we ask the device to do + speed configuration it can see all the intended device state in + full */ - -- /* 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]); ++ + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *adev = &ap->device[i]; + /* Choose the best data xfer mode */ @@ -1590,7 +1639,14 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + rc = ata_host_set_pio(ap, adev); + if (rc) + goto err_out; -+ + +- /* 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]); + /* step 2: if that xfer mode isn't PIO, set host DMA timings */ + if (xfer_shift[i] != ATA_SHIFT_PIO) { + ata_host_set_dma(ap, adev, xfer_mode[i], xfer_shift[i]); @@ -1622,7 +1678,118 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 if (ap->ops->post_set_mode) ap->ops->post_set_mode(ap); -@@ -2256,76 +2365,57 @@ +@@ -2200,132 +2310,126 @@ + } + + static const char * const ata_dma_blacklist [] = { +- "WDC AC11000H", +- "WDC AC22100H", +- "WDC AC32500H", +- "WDC AC33100H", +- "WDC AC31600H", +- "WDC AC32100H", +- "WDC AC23200L", +- "Compaq CRD-8241B", +- "CRD-8400B", +- "CRD-8480B", +- "CRD-8482B", +- "CRD-84", +- "SanDisk SDP3B", +- "SanDisk SDP3B-64", +- "SANYO CD-ROM CRD", +- "HITACHI CDR-8", +- "HITACHI CDR-8335", +- "HITACHI CDR-8435", +- "Toshiba CD-ROM XM-6202B", +- "TOSHIBA CD-ROM XM-1702BC", +- "CD-532E-A", +- "E-IDE CD-ROM CR-840", +- "CD-ROM Drive/F5A", +- "WPI CDD-820", +- "SAMSUNG CD-ROM SC-148C", +- "SAMSUNG CD-ROM SC", +- "SanDisk SDP3B-64", +- "ATAPI CD-ROM DRIVE 40X MAXIMUM", +- "_NEC DV5800A", ++ "WDC AC11000H", NULL, ++ "WDC AC22100H", NULL, ++ "WDC AC32500H", NULL, ++ "WDC AC33100H", NULL, ++ "WDC AC31600H", NULL, ++ "WDC AC32100H", "24.09P07", ++ "WDC AC23200L", "21.10N21", ++ "Compaq CRD-8241B", NULL, ++ "CRD-8400B", NULL, ++ "CRD-8480B", NULL, ++ "CRD-8482B", NULL, ++ "CRD-84", NULL, ++ "SanDisk SDP3B", NULL, ++ "SanDisk SDP3B-64", NULL, ++ "SANYO CD-ROM CRD", NULL, ++ "HITACHI CDR-8", NULL, ++ "HITACHI CDR-8335", NULL, ++ "HITACHI CDR-8435", NULL, ++ "Toshiba CD-ROM XM-6202B", NULL, ++ "TOSHIBA CD-ROM XM-1702BC", NULL, ++ "CD-532E-A", NULL, ++ "E-IDE CD-ROM CR-840", NULL, ++ "CD-ROM Drive/F5A", NULL, ++ "WPI CDD-820", NULL, ++ "SAMSUNG CD-ROM SC-148C", NULL, ++ "SAMSUNG CD-ROM SC", NULL, ++ "SanDisk SDP3B-64", NULL, ++ "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL, ++ "_NEC DV5800A", NULL, ++ "SAMSUNG CD-ROM SN-124", "N001" + }; + +-static int ata_dma_blacklisted(const struct ata_device *dev) ++static int ata_strim(char *s, size_t len) + { +- unsigned char model_num[40]; +- char *s; +- unsigned int len; +- int i; +- +- 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)); ++ len = strnlen(s, len); + + /* ATAPI specifies that empty space is blank-filled; remove blanks */ + while ((len > 0) && (s[len - 1] == ' ')) { + len--; + s[len] = 0; + } ++ return len; ++} + +- for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++) +- if (!strncmp(ata_dma_blacklist[i], s, len)) +- return 1; ++static int ata_dma_blacklisted(const struct ata_device *dev) ++{ ++ unsigned char model_num[40]; ++ unsigned char model_rev[16]; ++ unsigned int nlen, rlen; ++ int i; + ++ ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS, ++ sizeof(model_num)); ++ ata_dev_id_string(dev->id, model_rev, ATA_ID_FW_REV_OFS, ++ sizeof(model_rev)); ++ nlen = ata_strim(model_num, sizeof(model_num)); ++ rlen = ata_strim(model_rev, sizeof(model_rev)); ++ ++ for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i += 2) { ++ if (!strncmp(ata_dma_blacklist[i], model_num, nlen)) { ++ if (ata_dma_blacklist[i+1] == NULL) ++ return 1; ++ if (!strncmp(ata_dma_blacklist[i], model_rev, rlen)) ++ return 1; ++ } ++ } return 0; } @@ -1632,9 +1799,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 - const struct ata_device *master, *slave; unsigned int mask; + struct ata_host_set *hs = ap->host_set; - -- master = &ap->device[0]; -- slave = &ap->device[1]; ++ + if (!ata_dev_present(adev)) + return 0xFF; /* Drive isn't limiting anything */ + @@ -1644,11 +1809,13 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + mask &= tmp_mode; + } -- assert (ata_dev_present(master) || ata_dev_present(slave)); +- master = &ap->device[0]; +- slave = &ap->device[1]; + /* + * Enforce simplex rules if host is simplex + */ -+ + +- assert (ata_dev_present(master) || ata_dev_present(slave)); + if (hs->host_set_flags & ATA_HOST_SIMPLEX) { + if (hs->simplex_claimed) { + if (shift != ATA_SHIFT_PIO) @@ -1676,6 +1843,9 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + mask = 0; + ata_pr_blacklisted(ap, adev); } ++ /* 40 pin cable enforcement */ ++ if (ap->cbl == ATA_CBL_PATA40) ++ mask &= ~ATA_UDMA_MASK_40C; } else if (shift == ATA_SHIFT_MWDMA) { mask = ap->mwdma_mask; @@ -1692,11 +1862,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 - mask = 0; - ata_pr_blacklisted(ap, slave); - } -+ mask &= (adev->id[ATA_ID_MWDMA_MODES] & 0x07); -+ if (ata_dma_blacklisted(adev)) { -+ mask = 0; -+ ata_pr_blacklisted(ap, adev); - } +- } - } - else if (shift == ATA_SHIFT_PIO) { - mask = ap->pio_mask; @@ -1717,14 +1883,19 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 - tmp_mode <<= 3; - tmp_mode |= 0x7; - mask &= tmp_mode; -- } ++ mask &= (adev->id[ATA_ID_MWDMA_MODES] & 0x07); ++ if (ata_dma_blacklisted(adev)) { ++ mask = 0; ++ ata_pr_blacklisted(ap, adev); + } - } - else { -+ } else if (shift != ATA_SHIFT_PIO) { - mask = 0xffffffff; /* shut up compiler warning */ - BUG(); - } - +- mask = 0xffffffff; /* shut up compiler warning */ +- BUG(); +- } +- ++ } else if (shift != ATA_SHIFT_PIO) ++ panic("gmm:bad shift"); /* BUG confuses the compiler */ + /* + * Allow the controller to see the proposed mode and + * device data to do any custom filtering rules. @@ -1734,7 +1905,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 return mask; } -@@ -2345,6 +2435,7 @@ +@@ -2345,6 +2449,7 @@ /** * ata_choose_xfer_mode - attempt to find best transfer mode * @ap: Port for which an xfer mode will be selected @@ -1742,7 +1913,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 * @xfer_mode_out: (output) SET FEATURES - XFER MODE code * @xfer_shift_out: (output) bit shift that selects this mode * -@@ -2359,6 +2450,7 @@ +@@ -2359,6 +2464,7 @@ */ static int ata_choose_xfer_mode(const struct ata_port *ap, @@ -1750,7 +1921,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 u8 *xfer_mode_out, unsigned int *xfer_shift_out) { -@@ -2367,7 +2459,7 @@ +@@ -2367,7 +2473,7 @@ for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) { shift = xfer_mode_classes[i].shift; @@ -1759,7 +1930,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 x = fgb(mask); if (x >= 0) { -@@ -3000,6 +3092,7 @@ +@@ -3000,6 +3106,7 @@ /** * ata_mmio_data_xfer - Transfer data by MMIO * @ap: port to read/write @@ -1767,7 +1938,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 * @buf: data buffer * @buflen: buffer length * @write_data: read/write -@@ -3010,8 +3103,8 @@ +@@ -3010,8 +3117,8 @@ * Inherited from caller. */ @@ -1778,7 +1949,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 { unsigned int i; unsigned int words = buflen >> 1; -@@ -3045,6 +3138,7 @@ +@@ -3045,6 +3152,7 @@ /** * ata_pio_data_xfer - Transfer data by PIO * @ap: port to read/write @@ -1786,7 +1957,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 * @buf: data buffer * @buflen: buffer length * @write_data: read/write -@@ -3055,11 +3149,11 @@ +@@ -3055,11 +3163,11 @@ * Inherited from caller. */ @@ -1801,7 +1972,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 /* Transfer multiple of 2 bytes */ if (write_data) outsw(ap->ioaddr.data_addr, buf, words); -@@ -3082,36 +3176,55 @@ +@@ -3082,36 +3190,55 @@ } /** @@ -1875,7 +2046,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 } /** -@@ -3157,7 +3270,7 @@ +@@ -3157,7 +3284,7 @@ /* do the actual data transfer */ do_write = (qc->tf.flags & ATA_TFLAG_WRITE); @@ -1884,7 +2055,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 kunmap(page); } -@@ -3204,7 +3317,7 @@ +@@ -3204,7 +3331,7 @@ ap->id, bytes); for (i = 0; i < words; i++) @@ -1893,7 +2064,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 ap->hsm_task_state = HSM_ST_LAST; return; -@@ -3239,7 +3352,7 @@ +@@ -3239,7 +3366,7 @@ DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); /* do the actual data transfer */ @@ -1902,7 +2073,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 kunmap(page); -@@ -3948,14 +4061,15 @@ +@@ -3948,14 +4075,15 @@ void ata_bmdma_irq_clear(struct ata_port *ap) { @@ -1926,7 +2097,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 } -@@ -4194,12 +4308,12 @@ +@@ -4194,12 +4322,12 @@ */ spin_lock_irqsave(&ap->host_set->lock, flags); ap->flags &= ~ATA_FLAG_NOINTR; @@ -1941,7 +2112,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 /* PIO commands are handled by polling */ ap->hsm_task_state = HSM_ST; -@@ -4505,7 +4619,7 @@ +@@ -4505,7 +4633,7 @@ * Number of ports registered. Zero on error (no ports registered). */ @@ -1950,7 +2121,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 { unsigned int count = 0, i; struct device *dev = ent->dev; -@@ -4525,6 +4639,9 @@ +@@ -4525,6 +4653,9 @@ host_set->mmio_base = ent->mmio_base; host_set->private_data = ent->private_data; host_set->ops = ent->port_ops; @@ -1960,7 +2131,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 /* register each port bound to this device */ for (i = 0; i < ent->n_ports; i++) { -@@ -4536,6 +4653,14 @@ +@@ -4536,6 +4667,14 @@ goto err_out; host_set->ports[i] = ap; @@ -1975,7 +2146,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) | (ap->mwdma_mask << ATA_SHIFT_MWDMA) | (ap->pio_mask << ATA_SHIFT_PIO); -@@ -4552,6 +4677,7 @@ +@@ -4552,6 +4691,7 @@ ent->irq); ata_chk_status(ap); @@ -1983,7 +2154,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 host_set->ops->irq_clear(ap); count++; } -@@ -4605,7 +4731,8 @@ +@@ -4605,7 +4745,8 @@ ata_scsi_scan_host(ap); } @@ -1993,7 +2164,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 VPRINTK("EXIT, returning %u\n", ent->n_ports); return ent->n_ports; /* success */ -@@ -4779,6 +4906,7 @@ +@@ -4779,6 +4920,7 @@ { struct ata_probe_ent *probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); @@ -2001,7 +2172,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 int p = 0; if (!probe_ent) -@@ -4793,7 +4921,13 @@ +@@ -4793,7 +4935,13 @@ probe_ent->port[p].altstatus_addr = probe_ent->port[p].ctl_addr = pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; @@ -2016,7 +2187,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 ata_std_ports(&probe_ent->port[p]); p++; } -@@ -4803,7 +4937,14 @@ +@@ -4803,7 +4951,14 @@ probe_ent->port[p].altstatus_addr = probe_ent->port[p].ctl_addr = pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; @@ -2032,7 +2203,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 ata_std_ports(&probe_ent->port[p]); p++; } -@@ -4815,6 +4956,7 @@ +@@ -4815,6 +4970,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num) { struct ata_probe_ent *probe_ent; @@ -2040,7 +2211,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); if (!probe_ent) -@@ -4840,7 +4982,13 @@ +@@ -4840,7 +4996,13 @@ probe_ent->port[0].ctl_addr = 0x376; break; } @@ -2055,7 +2226,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 ata_std_ports(&probe_ent->port[0]); return probe_ent; } -@@ -5081,6 +5229,33 @@ +@@ -5081,6 +5243,33 @@ pci_set_master(pdev); return 0; } @@ -2089,7 +2260,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 #endif /* CONFIG_PCI */ -@@ -5158,6 +5333,10 @@ +@@ -5158,6 +5347,10 @@ EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear); EXPORT_SYMBOL_GPL(ata_bmdma_status); EXPORT_SYMBOL_GPL(ata_bmdma_stop); @@ -2100,7 +2271,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 EXPORT_SYMBOL_GPL(ata_port_probe); EXPORT_SYMBOL_GPL(sata_phy_reset); EXPORT_SYMBOL_GPL(__sata_phy_reset); -@@ -5175,6 +5354,7 @@ +@@ -5175,6 +5368,7 @@ EXPORT_SYMBOL_GPL(ata_dev_config); EXPORT_SYMBOL_GPL(ata_scsi_simulate); @@ -2108,7 +2279,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 EXPORT_SYMBOL_GPL(ata_pio_need_iordy); EXPORT_SYMBOL_GPL(ata_timing_compute); EXPORT_SYMBOL_GPL(ata_timing_merge); -@@ -5187,6 +5367,8 @@ +@@ -5187,6 +5381,8 @@ EXPORT_SYMBOL_GPL(ata_pci_remove_one); EXPORT_SYMBOL_GPL(ata_pci_device_suspend); EXPORT_SYMBOL_GPL(ata_pci_device_resume); @@ -5049,8 +5220,8 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5530.c linux-2.6.16-rc4/drivers/scsi/pata_cs5530.c --- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5530.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_cs5530.c 2006-02-16 15:43:34.000000000 +0000 -@@ -0,0 +1,340 @@ ++++ linux-2.6.16-rc4/drivers/scsi/pata_cs5530.c 2006-02-21 16:44:52.000000000 +0000 +@@ -0,0 +1,371 @@ +/* + * pata-cs5530.c - CS5530 PATA for new ATA layer + * (C) 2005 Red Hat Inc @@ -5085,9 +5256,10 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 +#include <linux/delay.h> +#include <scsi/scsi_host.h> +#include <linux/libata.h> ++#include <linux/dmi.h> + +#define DRV_NAME "cs5530" -+#define DRV_VERSION "0.3" ++#define DRV_VERSION "0.4" + +/** + * cs5530_set_piomode - PIO setup @@ -5254,6 +5426,26 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + .host_stop = ata_host_stop +}; + ++static struct dmi_system_id __initdata palmax_dmi_table[] = { ++ { ++ .ident = "Palmax PD1100", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Cyrix"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Caddis"), ++ }, ++ }, ++ { } ++}; ++ ++static int cs5530_is_palmax(void) ++{ ++ if (dmi_check_system(palmax_dmi_table)) { ++ printk(KERN_INFO "Palmax PD1100: Disabling DMA on docking port.\n"); ++ return 1; ++ } ++ return 0; ++} ++ +/** + * cs5530_init_one - Initialise a CS5530 + * @dev: PCI device @@ -5276,6 +5468,13 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + .udma_mask = 0x07, + .port_ops = &cs5530_port_ops + }; ++ /* The docking connector doesn't do UDMA, and it seems not MWDMA */ ++ static struct ata_port_info info_palmax_secondary = { ++ .sht = &cs5530_sht, ++ .host_flags = ATA_FLAG_SLAVE_POSS, ++ .pio_mask = 0x1f, ++ .port_ops = &cs5530_port_ops ++ }; + static struct ata_port_info *port_info[2] = { &info, &info }; + + dev = NULL; @@ -5348,6 +5547,9 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + pci_dev_put(master_0); + pci_dev_put(cs5530_0); + ++ if (cs5530_is_palmax()) ++ port_info[1] = &info_palmax_secondary; ++ + /* Now kick off ATA set up */ + return ata_pci_init_one(dev, port_info, 2); + @@ -11929,7 +12131,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 +module_exit(opti_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pcmcia.c linux-2.6.16-rc4/drivers/scsi/pata_pcmcia.c --- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pcmcia.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_pcmcia.c 2006-01-21 16:55:56.000000000 +0000 ++++ linux-2.6.16-rc4/drivers/scsi/pata_pcmcia.c 2006-02-20 17:26:30.000000000 +0000 @@ -0,0 +1,406 @@ +/* + * pata-pcmcia.c - PCMCIA PATA controller driver. @@ -12310,7 +12512,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + +static struct pcmcia_driver pcmcia_driver = { + .owner = THIS_MODULE, -+ .drv { ++ .drv = { + .name = DRV_NAME, + }, + .id_table = pcmcia_devices, @@ -17957,6 +18159,18 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 + +module_init(via_init); +module_exit(via_exit); +diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pdc_adma.c linux-2.6.16-rc4/drivers/scsi/pdc_adma.c +--- linux.vanilla-2.6.16-rc4/drivers/scsi/pdc_adma.c 2006-02-20 11:22:25.000000000 +0000 ++++ linux-2.6.16-rc4/drivers/scsi/pdc_adma.c 2006-02-23 13:15:50.480287896 +0000 +@@ -322,7 +322,7 @@ + = (pFLAGS & pEND) ? 0 : cpu_to_le32(pp->pkt_dma + i + 4); + i += 4; + +- VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", nelem, ++ VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4, + (unsigned long)addr, len); + } + return i; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_mv.c linux-2.6.16-rc4/drivers/scsi/sata_mv.c --- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_mv.c 2006-02-20 11:22:25.000000000 +0000 +++ linux-2.6.16-rc4/drivers/scsi/sata_mv.c 2006-02-20 11:28:03.000000000 +0000 @@ -18142,7 +18356,7 @@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6 #define ata_id_u64(id,n) \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/include/linux/libata.h linux-2.6.16-rc4/include/linux/libata.h --- linux.vanilla-2.6.16-rc4/include/linux/libata.h 2006-02-20 11:22:26.000000000 +0000 -+++ linux-2.6.16-rc4/include/linux/libata.h 2006-02-16 15:41:24.000000000 +0000 ++++ linux-2.6.16-rc4/include/linux/libata.h 2006-02-23 13:28:56.634774248 +0000 @@ -41,7 +41,7 @@ #undef ATA_VERBOSE_DEBUG /* yet more debugging output */ #undef ATA_IRQ_TRAP /* define to ack screaming irqs */ diff --git a/packages/linux/ixp4xx-kernel_2.6.16-rc4.bb b/packages/linux/ixp4xx-kernel_2.6.16-rc4-git5.bb index 4c6abdcda6..e47f20a7ab 100644 --- a/packages/linux/ixp4xx-kernel_2.6.16-rc4.bb +++ b/packages/linux/ixp4xx-kernel_2.6.16-rc4-git5.bb @@ -8,16 +8,16 @@ PR_CONFIG = "0" # Increment the number below (i.e. the digits after PR) when # making changes within this file or for changes to the patches # applied to the kernel. -PR = "r2.${PR_CONFIG}" +PR = "r0.${PR_CONFIG}" include ixp4xx-kernel.inc -RPSRC = "http://www.rpsys.net/openzaurus/patches" +# RPSRC = "http://www.rpsys.net/openzaurus/patches" # IXP4XX_PATCHES - full list of patches to apply IXP4XX_PATCHES = "" -IXP4XX_PATCHES += "file://patch-2.6.16-rc4-ide1;patch=1" +IXP4XX_PATCHES += "file://patch-2.6.16-rc4-ide2;patch=1" IXP4XX_PATCHES += "file://leds-class.patch;patch=1" IXP4XX_PATCHES += "file://06-remove-extraversion.patch;patch=1" IXP4XX_PATCHES += "file://10-mtdpart-redboot-fis-byteswap.patch;patch=1" @@ -29,11 +29,9 @@ IXP4XX_PATCHES += "file://45-eeprom-notifier.patch;patch=1" IXP4XX_PATCHES += "file://48-setup-byteswap-cmdline.patch;patch=1" IXP4XX_PATCHES += "file://50-i2c-bus-ixp4xx-hwmon.patch;patch=1" IXP4XX_PATCHES += "file://50-hwmon-ad741x.patch;patch=1" -IXP4XX_PATCHES += "file://61-nslu2-beeper.patch;patch=1" IXP4XX_PATCHES += "file://65-loft-config.patch;patch=1" IXP4XX_PATCHES += "file://70-artop-latency.patch;patch=1" -IXP4XX_PATCHES += "file://80-nas100d-fix-i2c.patch;patch=1" -IXP4XX_PATCHES += "file://81-nslu2-power.patch;patch=1" +IXP4XX_PATCHES += "file://75-dsmg600.patch;patch=1" IXP4XX_PATCHES += "file://82-nas100d-power.patch;patch=1" IXP4XX_PATCHES += "file://85-timer.patch;patch=1" IXP4XX_PATCHES += "file://91-maclist.patch;patch=1" @@ -42,9 +40,11 @@ IXP4XX_PATCHES += "file://92-nslu2-maclist.patch;patch=1" IXP4XX_PATCHES += "file://94-nas100d-setup.patch;patch=1" IXP4XX_PATCHES += "file://94-nslu2-setup.patch;patch=1" IXP4XX_PATCHES += "file://94-loft-setup.patch;patch=1" +IXP4XX_PATCHES += "file://96-pata-ixp4xx.patch;patch=1" IXP4XX_PATCHES += "file://96-nas100d-leds.patch;patch=1" IXP4XX_PATCHES += "file://96-nslu2-leds.patch;patch=1" IXP4XX_PATCHES += "file://97-ds101-setup.patch;patch=1" IXP4XX_PATCHES += "file://97-ds101-includes.patch;patch=1" IXP4XX_PATCHES += "file://97-ds101-pci.patch;patch=1" IXP4XX_PATCHES += "file://97-ds101-buttons.patch;patch=1" +IXP4XX_PATCHES += "file://97-ds101-doc.patch;patch=1" |