diff options
Diffstat (limited to 'packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide2')
-rw-r--r-- | packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide2 | 18474 |
1 files changed, 0 insertions, 18474 deletions
diff --git a/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide2 b/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide2 deleted file mode 100644 index ea23ff47d3..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide2 +++ /dev/null @@ -1,18474 +0,0 @@ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/arch/i386/pci/fixup.c linux-2.6.16-rc4/arch/i386/pci/fixup.c ---- linux.vanilla-2.6.16-rc4/arch/i386/pci/fixup.c 2006-02-20 11:22:15.000000000 +0000 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/pci/probe.c linux-2.6.16-rc4/drivers/pci/probe.c ---- linux.vanilla-2.6.16-rc4/drivers/pci/probe.c 2006-02-20 11:22:17.000000000 +0000 -+++ linux-2.6.16-rc4/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 */ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/ata_generic.c linux-2.6.16-rc4/drivers/scsi/ata_generic.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/ata_generic.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/ata_generic.c 2006-02-16 15:35:41.000000000 +0000 -@@ -0,0 +1,241 @@ -+/* -+ * 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_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 --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-20 20:06:17.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-ac7" - - 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, -@@ -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 */ --#if 0 - .mwdma_mask = 0x06, /* mwdma1-2 */ --#else -- .mwdma_mask = 0x00, /* mwdma broken */ --#endif -- .udma_mask = 0x3f, /* udma0-5 */ -- .port_ops = &piix_pata_ops, -+ .udma_mask = ATA_UDMA6, -+ .port_ops = &ich_pata_ops, - }, - -- /* 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 */ --#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, - }, - -- /* 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: 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 = ATA_UDMA4, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* 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 = ATA_UDMA5, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* 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 = ATA_UDMA5, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* 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 = ATA_UDMA5, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* 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 = ATA_UDMA5, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* piix3_pata: 10 */ -+ { -+ .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: 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 = ATA_UDMA5, -+ .port_ops = &piix_pata_ops, -+ }, -+ -+ /* 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 = ATA_UDMA4, /* UDMA66 */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* 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 = ATA_UDMA6, /* UDMA133 */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* 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 = ATA_UDMA6, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* 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 = ATA_UDMA5, -+ .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; -+ u16 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_word(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_word(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 -@@ -646,15 +967,15 @@ - pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); - pci_read_config_word(pdev, 0x41, &cfg); - /* Only on the original revision: IDE DMA can hang */ -- if(rev == 0x00) -+ if (rev == 0x00) - no_piix_dma = 1; - /* On all revisions below 5 PXB bus lock must be disabled for IDE */ -- else if(cfg & (1<<14) && rev < 5) -+ else if (cfg & (1<<14) && rev < 5) - no_piix_dma = 2; - } -- if(no_piix_dma) -+ if (no_piix_dma) - dev_printk(KERN_WARNING, &ata_dev->dev, "450NX errata present, disabling IDE DMA.\n"); -- if(no_piix_dma == 2) -+ if (no_piix_dma == 2) - dev_printk(KERN_WARNING, &ata_dev->dev, "A BIOS update may resolve this.\n"); - return no_piix_dma; - } -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-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 - -+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_NS87410 -+ tristate "Nat Semi NS87410 PATA support (Experimental)" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the National Semiconductor -+ NS87410 PCI-IDE 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 early PIIX PATA interfaces. -+ -+ 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 && PCMCIA -+ 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_PDC_OLD -+ tristate "Older Promise PATA controller support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the Promise 20246, 20262, 20263, -+ 20265 and 20267 adapters. -+ -+ 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_RADISYS -+ tristate "RADISYS 82600 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the RADISYS 82600 -+ PATA controllers via the new ATA layer -+ -+ If unsure, say N. -+ -+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 --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-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); - 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); -@@ -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; - } - -+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 */ -@@ -1485,10 +1535,24 @@ - ap->ops->phy_reset(ap); - if (ap->flags & ATA_FLAG_PORT_DISABLED) - goto err_out; -+ -+ /* The reset means we are in PIO 0, but the controller may not -+ yet be correctly set up and may have old BIOS settings, or just -+ no settings at all. Set all the devices to PIO 0 */ -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) -+ ap->device[i].pio_mode = XFER_PIO_0; - - for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *adev = & ap->device[i]; -+ -+ /* Set up the controller on this port for PIO 0. We must not -+ send the drive speed setting commands at this point */ -+ if (ap->ops->set_piomode) -+ ap->ops->set_piomode(ap, adev); -+ - ata_dev_identify(ap, i); -- if (ata_dev_present(&ap->device[i])) { -+ if (ata_dev_present(adev)) { - found = 1; - ata_dev_config(ap,i); - } -@@ -1497,7 +1561,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; - -@@ -1612,6 +1680,23 @@ - } - - /** -+ * ata_dev_pair - return other device on cable -+ * @ap: port -+ * @adev: device -+ * -+ * Obtain the other device on the same cable, or if none is -+ * present NULL is returned -+ */ -+ -+struct ata_device *ata_dev_pair(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct ata_device *pair = &ap->device[1 - adev->devno]; -+ if (!ata_dev_present(pair)) -+ return NULL; -+ return pair; -+} -+ -+/** - * ata_port_disable - Disable port. - * @ap: Port to be disabled. - * -@@ -1824,16 +1909,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 +1931,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 +1964,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 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]); -+ used_dma = 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); - -@@ -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; - } - --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); - } -+ /* 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; -- 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 { -- 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. -+ */ -+ if(ap->ops->mode_filter) -+ mask = ap->ops->mode_filter(ap, adev, mask, shift); - return mask; - } - -@@ -2345,6 +2449,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 +2464,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 +2473,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) { -@@ -3000,6 +3106,7 @@ - /** - * ata_mmio_data_xfer - Transfer data by MMIO - * @ap: port to read/write -+ * @adev: device to target - * @buf: data buffer - * @buflen: buffer length - * @write_data: read/write -@@ -3010,8 +3117,8 @@ - * Inherited from caller. - */ - --static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, -- unsigned int buflen, int write_data) -+void ata_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; -@@ -3045,6 +3152,7 @@ - /** - * ata_pio_data_xfer - Transfer data by PIO - * @ap: port to read/write -+ * @adev: device to target - * @buf: data buffer - * @buflen: buffer length - * @write_data: read/write -@@ -3055,11 +3163,11 @@ - * Inherited from caller. - */ - --static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf, -- unsigned int buflen, int write_data) -+void ata_pio_data_xfer(struct ata_port *ap, struct ata_device *adev, -+ 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 +3190,55 @@ - } - - /** -- * 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 -+ * @adev: device to target - * @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, -- unsigned int buflen, int do_write) -+void ata_pio_data_xfer_noirq(struct ata_port *ap, struct ata_device *adev, -+ 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, adev, 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 -+ * @adev: device to target -+ * @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, struct ata_device *adev, -+ 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, adev, buf, buflen, do_write); -+ local_irq_restore(flags); - } - - /** -@@ -3157,7 +3284,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, qc->dev, buf, ATA_SECT_SIZE, do_write); - - kunmap(page); - } -@@ -3204,7 +3331,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, qc->dev, (unsigned char*)pad_buf, 2, do_write); - - ap->hsm_task_state = HSM_ST_LAST; - return; -@@ -3239,7 +3366,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, qc->dev, buf, count, do_write); - - kunmap(page); - -@@ -3948,14 +4075,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); -+ } -+ } - } - - -@@ -4194,12 +4322,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->dev, 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->dev, qc->cdb, ap->cdb_len, 1); - - /* PIO commands are handled by polling */ - ap->hsm_task_state = HSM_ST; -@@ -4505,7 +4633,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; -@@ -4525,6 +4653,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++) { -@@ -4536,6 +4667,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); -@@ -4552,6 +4691,7 @@ - ent->irq); - - ata_chk_status(ap); -+ /* This last call probably should be conditional on bmdma */ - host_set->ops->irq_clear(ap); - count++; - } -@@ -4605,7 +4745,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 */ -@@ -4779,6 +4920,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) -@@ -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; -- 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++; - } -@@ -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; -- 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++; - } -@@ -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; -+ unsigned long bmdma; - - probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); - if (!probe_ent) -@@ -4840,7 +4996,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; - } -@@ -5081,6 +5243,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 */ - - -@@ -5158,6 +5347,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); -@@ -5175,6 +5368,7 @@ - EXPORT_SYMBOL_GPL(ata_dev_config); - EXPORT_SYMBOL_GPL(ata_scsi_simulate); - -+EXPORT_SYMBOL_GPL(ata_dev_pair); - EXPORT_SYMBOL_GPL(ata_pio_need_iordy); - EXPORT_SYMBOL_GPL(ata_timing_compute); - EXPORT_SYMBOL_GPL(ata_timing_merge); -@@ -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); -+EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); -+ - #endif /* CONFIG_PCI */ - - EXPORT_SYMBOL_GPL(ata_device_suspend); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/Makefile linux-2.6.16-rc4/drivers/scsi/Makefile ---- linux.vanilla-2.6.16-rc4/drivers/scsi/Makefile 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/Makefile 2006-02-17 18:20:44.000000000 +0000 -@@ -139,6 +139,42 @@ - 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_NS87410) += libata.o pata_ns87410.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_PDC_OLD) += libata.o pata_pdc202xx_old.o -+obj-$(CONFIG_SCSI_PATA_QDI) += libata.o pata_qdi.o -+obj-$(CONFIG_SCSI_PATA_RADISYS) += libata.o pata_radisys.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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_ali.c linux-2.6.16-rc4/drivers/scsi/pata_ali.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_ali.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_ali.c 2006-02-20 12:28:04.000000000 +0000 -@@ -0,0 +1,606 @@ -+/* -+ * 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.2.2" -+ -+/** -+ * 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; /* Command timing */ -+ int drwt = 0x5A + 4 * ap->hard_port_no + adev->devno; /* R/W timing */ -+ int udmat = 0x56 + ap->hard_port_no; /* UDMA timing */ -+ int shift = 4 * adev->devno; -+ u8 udma; -+ -+ if (ultra == 0) { -+ /* FIXME: We ought to set up pcas not rely on the BIOS */ -+ /* 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 = ata_dev_pair(ap, adev); -+ 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 (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) -+{ -+ if(ap->host->max_sectors > 255) { -+ ap->host->max_sectors = 255; -+ ap->host->hostt->max_sectors = 255; -+ } -+ 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(pdev->bus, 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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_amd.c linux-2.6.16-rc4/drivers/scsi/pata_amd.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_amd.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_amd.c 2006-02-16 15:37:39.000000000 +0000 -@@ -0,0 +1,650 @@ -+/* -+ * 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.3" -+ -+/** -+ * 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); -+ struct ata_device *peer = ata_dev_pair(ap, adev); -+ 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 (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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_artop.c linux-2.6.16-rc4/drivers/scsi/pata_artop.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_artop.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_artop.c 2006-02-07 13:41:48.000000000 +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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_atiixp.c linux-2.6.16-rc4/drivers/scsi/pata_atiixp.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_atiixp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_atiixp.c 2006-02-07 13:42:02.000000000 +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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cmd64x.c linux-2.6.16-rc4/drivers/scsi/pata_cmd64x.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cmd64x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_cmd64x.c 2006-02-16 15:34:39.000000000 +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.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 = ata_dev_pair(ap, adev); -+ -+ if (pair) { -+ struct ata_timing tp; -+ 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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5520.c linux-2.6.16-rc4/drivers/scsi/pata_cs5520.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5520.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_cs5520.c 2006-02-20 13:17:11.000000000 +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.4" -+ -+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) -+{ -+ static const int dma_xlate[3] = { XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 }; -+ cs5520_set_timings(ap, adev, dma_xlate[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 --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-21 16:44:52.000000000 +0000 -@@ -0,0 +1,371 @@ -+/* -+ * 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> -+#include <linux/dmi.h> -+ -+#define DRV_NAME "cs5530" -+#define DRV_VERSION "0.4" -+ -+/** -+ * 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 track the last DMA setup in order to minimise -+ * reloads. -+ */ -+ -+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); -+ -+ /* Remember the last DMA setup we did */ -+ -+ ap->private_data = adev; -+} -+ -+/** -+ * cs5530_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. Specifically we have a problem that there is only -+ * one MWDMA/UDMA bit. -+ */ -+ -+static int cs5530_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ struct ata_device *prev = ap->private_data; -+ -+ /* See if the DMA settings could be wrong */ -+ if (adev->dma_mode != 0 && adev != prev && prev != NULL) { -+ /* Maybe, but do the channels match MWDMA/UDMA ? */ -+ if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) || -+ (adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0)) -+ /* Switch the mode bits */ -+ cs5530_set_dmamode(ap, adev); -+ } -+ -+ return ata_qc_issue_prot(qc); -+} -+ -+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 = { -+ .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 = cs5530_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 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 -+ * @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 -+ }; -+ /* 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; -+ 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); -+ -+ 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); -+ -+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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5535.c linux-2.6.16-rc4/drivers/scsi/pata_cs5535.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5535.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_cs5535.c 2006-02-16 15:37:21.000000000 +0000 -@@ -0,0 +1,286 @@ -+/* -+ * 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.2.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 = ata_dev_pair(ap, adev); -+ -+ int mode = adev->pio_mode - XFER_PIO_0; -+ int cmdmode = mode; -+ -+ /* Command timing has to be for the lowest of the pair of devices */ -+ if (pair) { -+ int pairmode = pair->pio_mode - XFER_PIO_0; -+ cmdmode = min(mode, pairmode); -+ /* 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); -+ } -+ /* Write the drive timing register */ -+ wrmsr(ATAC_CH0D0_PIO + 2 * adev->devno, -+ pio_cmd_timings[cmdmode] << 16 | pio_timings[mode], 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 -+ * -+ */ -+ -+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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cypress.c linux-2.6.16-rc4/drivers/scsi/pata_cypress.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cypress.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_cypress.c 2006-02-16 15:37:46.000000000 +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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_efar.c linux-2.6.16-rc4/drivers/scsi/pata_efar.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_efar.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_efar.c 2006-02-16 15:37:53.000000000 +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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt34x.c linux-2.6.16-rc4/drivers/scsi/pata_hpt34x.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt34x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_hpt34x.c 2006-02-16 15:38:47.000000000 +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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt366.c linux-2.6.16-rc4/drivers/scsi/pata_hpt366.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt366.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_hpt366.c 2006-02-16 15:45:36.000000000 +0000 -@@ -0,0 +1,479 @@ -+/* -+ * 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 -+ * Maybe 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.2" -+ -+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 } -+}; -+ -+static const char *bad_ata33[] = { -+ "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2", -+ "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", -+ "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", -+ "Maxtor 90510D4", -+ "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2", -+ "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", -+ "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", -+ NULL -+}; -+ -+static const char *bad_ata66_4[] = { -+ "IBM-DTLA-307075", -+ "IBM-DTLA-307060", -+ "IBM-DTLA-307045", -+ "IBM-DTLA-307030", -+ "IBM-DTLA-307020", -+ "IBM-DTLA-307015", -+ "IBM-DTLA-305040", -+ "IBM-DTLA-305030", -+ "IBM-DTLA-305020", -+ "IC35L010AVER07-0", -+ "IC35L020AVER07-0", -+ "IC35L030AVER07-0", -+ "IC35L040AVER07-0", -+ "IC35L060AVER07-0", -+ "WDC AC310200R", -+ NULL -+}; -+ -+static const char *bad_ata66_3[] = { -+ "WDC AC310200R", -+ NULL -+}; -+ -+static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[]) -+{ -+ unsigned char model_num[40]; -+ char *s; -+ unsigned int len; -+ int i = 0; -+ -+ 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)); -+ -+ /* ATAPI specifies that empty space is blank-filled; remove blanks */ -+ while ((len > 0) && (s[len - 1] == ' ')) { -+ len--; -+ s[len] = 0; -+ } -+ -+ while(list[i] != NULL) { -+ if (!strncmp(list[i], s, len)) { -+ printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n", -+ modestr, list[i]); -+ return 1; -+ } -+ i++; -+ } -+ return 0; -+} -+ -+/** -+ * hpt366_filter - mode selection filter -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Block UDMA on devices that cause trouble with this controller. -+ */ -+ -+static unsigned int hpt366_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 mask; -+ if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) -+ return 0; -+ if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3)) -+ return mask & 0x07; -+ if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4)) -+ return mask & 0x0F; -+ return mask; -+} -+ -+/** -+ * 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, -+ .mode_filter = hpt366_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 = 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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt37x.c linux-2.6.16-rc4/drivers/scsi/pata_hpt37x.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt37x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_hpt37x.c 2006-02-16 15:45:27.000000000 +0000 -@@ -0,0 +1,1232 @@ -+/* -+ * 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 -+ * 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 "hpt37x" -+#define DRV_VERSION "0.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(); -+} -+ -+static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[]) -+{ -+ unsigned char model_num[40]; -+ char *s; -+ unsigned int len; -+ int i = 0; -+ -+ 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)); -+ -+ /* ATAPI specifies that empty space is blank-filled; remove blanks */ -+ while ((len > 0) && (s[len - 1] == ' ')) { -+ len--; -+ s[len] = 0; -+ } -+ -+ while(list[i] != NULL) { -+ if (!strncmp(list[i], s, len)) { -+ printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n", -+ modestr, list[i]); -+ return 1; -+ } -+ i++; -+ } -+ return 0; -+} -+ -+static const char *bad_ata33[] = { -+ "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2", -+ "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", -+ "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", -+ "Maxtor 90510D4", -+ "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2", -+ "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", -+ "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", -+ NULL -+}; -+ -+static const char *bad_ata100_5[] = { -+ "IBM-DTLA-307075", -+ "IBM-DTLA-307060", -+ "IBM-DTLA-307045", -+ "IBM-DTLA-307030", -+ "IBM-DTLA-307020", -+ "IBM-DTLA-307015", -+ "IBM-DTLA-305040", -+ "IBM-DTLA-305030", -+ "IBM-DTLA-305020", -+ "IC35L010AVER07-0", -+ "IC35L020AVER07-0", -+ "IC35L030AVER07-0", -+ "IC35L040AVER07-0", -+ "IC35L060AVER07-0", -+ "WDC AC310200R", -+ NULL -+}; -+ -+/** -+ * hpt370_filter - mode selection filter -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Block UDMA on devices that cause trouble with this controller. -+ */ -+ -+static unsigned int hpt370_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 mask; -+ if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) -+ return mask & 0x1F; -+ if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) -+ return mask & 0x1F; -+ return mask; -+} -+ -+/** -+ * hpt370a_filter - mode selection filter -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Block UDMA on devices that cause trouble with this controller. -+ */ -+ -+static unsigned int hpt370a_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 mask; -+ if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) -+ return mask & 0x1F; -+ return mask; -+} -+ -+/** -+ * 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 -+ */ -+ -+static struct ata_port_operations hpt370_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt370_set_piomode, -+ .set_dmamode = hpt370_set_dmamode, -+ .mode_filter = hpt370_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 = 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 HPT370A. Close to 370 but less filters -+ */ -+ -+static struct ata_port_operations hpt370a_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt370_set_piomode, -+ .set_dmamode = hpt370_set_dmamode, -+ .mode_filter = hpt370a_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 = 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 - 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 -+ }; -+ /* HPT370A - UDMA100 */ -+ static struct ata_port_info info_hpt370a = { -+ .sht = &hpt37x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &hpt370a_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_hpt370a; -+ 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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt3x2n.c linux-2.6.16-rc4/drivers/scsi/pata_hpt3x2n.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt3x2n.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_hpt3x2n.c 2006-02-16 15:36:58.000000000 +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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_isapnp.c linux-2.6.16-rc4/drivers/scsi/pata_isapnp.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_isapnp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_it8172.c linux-2.6.16-rc4/drivers/scsi/pata_it8172.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_it8172.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_it8172.c 2006-02-16 15:39:11.000000000 +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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_it821x.c linux-2.6.16-rc4/drivers/scsi/pata_it821x.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_it821x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_it821x.c 2006-02-20 12:27:55.000000000 +0000 -@@ -0,0 +1,743 @@ -+/* -+ * 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.1" -+ -+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 = ata_dev_pair(ap, adev); -+ -+ 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) */ -+ -+ /* Do we need a dev_config method ? */ -+ 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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_legacy.c linux-2.6.16-rc4/drivers/scsi/pata_legacy.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_legacy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_legacy.c 2006-02-16 15:33:52.000000000 +0000 -@@ -0,0 +1,672 @@ -+ -+/* -+ * 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.1" -+ -+#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, struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) -+{ -+ int slop = buflen & 3; -+ unsigned long flags; -+ -+ if (ata_id_has_dword_io(adev->id)) { -+ 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); -+ } -+ else -+ ata_pio_data_xfer_noirq(ap, adev, buf, buflen, write_data); -+} -+ -+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, 20000, 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, 20000, 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 = ata_dev_pair(ap, adev); -+ 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 = 1000000000 / 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 (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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_mpiix.c linux-2.6.16-rc4/drivers/scsi/pata_mpiix.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_mpiix.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_mpiix.c 2006-02-16 15:38:41.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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_netcell.c linux-2.6.16-rc4/drivers/scsi/pata_netcell.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_netcell.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_netcell.c 2006-02-08 14:05:57.000000000 +0000 -@@ -0,0 +1,176 @@ -+/* -+ * 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) -+{ -+ 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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_ns87410.c linux-2.6.16-rc4/drivers/scsi/pata_ns87410.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_ns87410.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_ns87410.c 2006-02-15 15:05:43.000000000 +0000 -@@ -0,0 +1,213 @@ -+/* -+ * pata_ns87410.c - National Semiconductor 87410 PATA for new ATA layer -+ * (C) 2006 Red Hat Inc -+ * Alan Cox <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 <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_ns87410" -+#define DRV_VERSION "0.1" -+ -+/** -+ * ns87410_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 ns87410_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static const struct pci_bits ns87410_enable_bits[] = { -+ { 0x43, 1, 0x08, 0x08 }, -+ { 0x47, 1, 0x08, 0x08 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &ns87410_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); -+} -+ -+/** -+ * ns87410_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program timing data. This is kept per channel not per device, -+ * and only affects the data port. -+ */ -+ -+static void ns87410_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; -+ u8 idetcr, idefr; -+ struct ata_timing at; -+ -+ static const u8 activebits[15] = { -+ 0, 1, 2, 3, 4, -+ 5, 5, 6, 6, 6, -+ 6, 7, 7, 7, 7 -+ }; -+ -+ static const u8 recoverbits[12] = { -+ 0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 7, 7 -+ }; -+ -+ pci_read_config_byte(pdev, port + 3, &idefr); -+ -+ if (ata_pio_need_iordy(adev)) -+ idefr |= 0x04; /* IORDY enable */ -+ else -+ idefr &= ~0x04; -+ -+ if (ata_timing_compute(adev, adev->pio_mode, &at, 30303, 1) < 0) { -+ dev_printk(KERN_ERR, &pdev->dev, "unknown mode %d.\n", adev->pio_mode); -+ return; -+ } -+ -+ at.active = FIT(at.active, 2, 16) - 2; -+ at.setup = FIT(at.setup, 1, 4) - 1; -+ at.recover = FIT(at.recover, 1, 12) - 1; -+ -+ idetcr = (at.setup << 6) | (recoverbits[at.recover] << 3) | activebits[at.active]; -+ -+ pci_write_config_byte(pdev, port, idetcr); -+ pci_write_config_byte(pdev, port + 3, idefr); -+ /* We use ap->private_data as a pointer to the device currently -+ loaded for timing */ -+ ap->private_data = adev; -+} -+ -+/** -+ * ns87410_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 ns87410_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) -+ ns87410_set_piomode(ap, adev); -+ -+ return ata_qc_issue_prot(qc); -+} -+ -+static struct scsi_host_template ns87410_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 ns87410_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = ns87410_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 = ns87410_phy_reset, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ns87410_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 ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &ns87410_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x0F, -+ .port_ops = &ns87410_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = {&info, &info}; -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static const struct pci_device_id ns87410[] = { -+ { PCI_DEVICE(0x100B, 0xD001), }, -+ { 0, }, -+}; -+ -+static struct pci_driver ns87410_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = ns87410, -+ .probe = ns87410_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init ns87410_init(void) -+{ -+ return pci_register_driver(&ns87410_pci_driver); -+} -+ -+ -+static void __exit ns87410_exit(void) -+{ -+ pci_unregister_driver(&ns87410_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Nat Semi 87410"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, ns87410); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(ns87410_init); -+module_exit(ns87410_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_oldpiix.c linux-2.6.16-rc4/drivers/scsi/pata_oldpiix.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_oldpiix.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_opti.c linux-2.6.16-rc4/drivers/scsi/pata_opti.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_opti.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_opti.c 2006-02-16 15:38:28.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.2" -+ -+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 = ata_dev_pair(ap, adev); -+ 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 (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 --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-02-20 17:26:30.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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pdc2027x.c linux-2.6.16-rc4/drivers/scsi/pata_pdc2027x.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pdc2027x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pdc202xx_old.c linux-2.6.16-rc4/drivers/scsi/pata_pdc202xx_old.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pdc202xx_old.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_pdc202xx_old.c 2006-02-20 13:19:57.000000000 +0000 -@@ -0,0 +1,428 @@ -+/* -+ * pata_pdc202xx_old.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/pdc202xx_old.c -+ * -+ * Initial revision -+ * -+ * TODO: -+ * Channel interlock/reset on both 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 "pata_pdc202xx_old" -+#define DRV_VERSION "0.1.2" -+ -+static void pdc2024x_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+ -+static void pdc2026x_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u16 cis; -+ -+ pci_read_config_word(pdev, 0x50, &cis); -+ if (cis & (1 << (10 + ap->hard_port_no))) -+ ap->cbl = ATA_CBL_PATA80; -+ else -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+ -+/** -+ * pdc_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 pdc_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int port = 0x60 + 4 * ap->hard_port_no + 2 * adev->devno; -+ static u16 pio_timing[5] = { -+ 0x0913, 0x050C , 0x0308, 0x0206, 0x0104 -+ }; -+ u8 r_ap, r_bp; -+ -+ /* FIFO, IORDY ? */ -+ pci_read_config_byte(pdev, port, &r_ap); -+ pci_read_config_byte(pdev, port + 1, &r_bp); -+ r_ap &= ~0x0F; -+ r_bp &= ~0x07; -+ r_ap |= (pio_timing[pio] >> 8); -+ r_bp |= (pio_timing[pio] & 0xFF); -+ pci_write_config_byte(pdev, port, r_ap); -+ pci_write_config_byte(pdev, port + 1, r_bp); -+} -+ -+/** -+ * pdc_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 pdc_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ pdc_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0); -+} -+ -+/** -+ * pdc_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 pdc_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int port = 0x60 + 4 * ap->hard_port_no + 2 * adev->devno; -+ static u8 udma_timing[6][2] = { -+ { 0x60, 0x03 }, /* 33 Mhz Clock */ -+ { 0x40, 0x02 }, -+ { 0x20, 0x01 }, -+ { 0x40, 0x02 }, /* 66 Mhz Clock */ -+ { 0x20, 0x01 }, -+ { 0x20, 0x01 } -+ }; -+ u8 r_bp, r_cp; -+ -+ pci_read_config_byte(pdev, port + 1, &r_bp); -+ pci_read_config_byte(pdev, port + 2, &r_cp); -+ -+ r_bp &= ~0xF0; -+ r_cp &= ~0x0F; -+ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ int speed = adev->dma_mode - XFER_UDMA_0; -+ r_bp |= udma_timing[speed][0]; -+ r_cp |= udma_timing[speed][1]; -+ -+ } else { -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ r_bp |= 0x60; -+ r_cp |= (5 - speed); -+ } -+ pci_write_config_byte(pdev, port + 1, r_bp); -+ pci_write_config_byte(pdev, port + 2, r_cp); -+ -+} -+ -+/** -+ * pdc2026x_reset_engine - Reset the DMA engine -+ * @ap: ATA interface -+ * -+ * Reset the 2026x DMA engine. This is not something we want to do, -+ * and we need to figure out how to serialize this across dual channel -+ * devices if it is neccessary. -+ * -+ * FIXME: Do we need to reset the other interface too ? -+ */ -+ -+static void pdc2026x_reset_engine(struct ata_port *ap) -+{ -+ unsigned long ctrl = ap->host_set->ports[0]->ioaddr.bmdma_addr + 0x1F; -+ -+ u8 val = inb(ctrl); -+ outb(val | 0x10, ctrl); -+ mdelay(100); -+ outb(val & ~0x10, ctrl); -+ mdelay(2000); /* Check - seems to be overkill, plus if needed -+ redo locking */ -+ /* Need to fix up speed info at this point */ -+} -+ -+/** -+ * pdc2026x_bmdma_start - DMA engine begin -+ * @qc: ATA command -+ * -+ * In UDMA3 or higher we have to clock switch for the duration of the -+ * DMA transfer sequence. -+ */ -+ -+static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ int sel66 = ap->hard_port_no ? 0x08: 0x02; -+ /* The clock bits are in the same register for both channels */ -+ unsigned long clock = ap->host_set->ports[0]->ioaddr.bmdma_addr + 0x11; -+ -+ /* Check we keep host_set level locking here */ -+ if (adev->dma_mode >= XFER_UDMA_2) -+ outb(inb(clock) | sel66, clock); -+ else -+ outb(inb(clock) & ~sel66, clock); -+ /* The DMA clocks may have been trashed by a reset. FIXME: make conditional -+ and move to qc_issue ? */ -+ pdc_set_dmamode(ap, qc->dev); -+ /* Activate DMA */ -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * pdc2026x_bmdma_end - DMA engine stop -+ * @qc: ATA command -+ * -+ * After a DMA completes we need to put the clock back to 33MHz for -+ * PIO timings. -+ */ -+ -+static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ int sel66 = ap->hard_port_no ? 0x08: 0x02; -+ /* The clock bits are in the same register for both channels */ -+ unsigned long clock = ap->host_set->ports[0]->ioaddr.bmdma_addr + 0x11; -+ -+ /* FIXME: Review LBA48 code in ide/pci driver */ -+ ata_bmdma_stop(qc); -+ /* Check we keep host_set level locking here */ -+ /* Flip back to 33Mhz for PIO */ -+ if (adev->dma_mode >= XFER_UDMA_2) -+ outb(inb(clock) & ~sel66, clock); -+} -+ -+/** -+ * pdc2026x_eng_timeout - command timeout -+ * @qc: command that timed out -+ * -+ * When the PDC2026x times out hit the controller over the head -+ * with a hammer before continuing. The reset unfortunately also -+ * resets the timing registers so we must reprogram these. -+ */ -+ -+static void pdc2026x_eng_timeout(struct ata_port *ap) -+{ -+ int i; -+ -+ /* Perform libata side housekeeping */ -+ ata_eng_timeout(ap); -+ -+ /* Reset the controller */ -+ pdc2026x_reset_engine(ap); -+ -+ /* Reprogram the device timings */ -+ for (i = 0; i < 2; i++) { -+ struct ata_device *adev = &ap->device[i]; -+ if (ata_dev_present(adev)) { -+ pdc_set_piomode(ap, adev); -+ if (adev->dma_mode) -+ pdc_set_dmamode(ap, adev); -+ } -+ } -+} -+ -+/** -+ * pdc2026x_dev_config - device setup hook -+ * @ap: ATA port -+ * @adev: newly found device -+ * -+ * Perform chip specific early setup. We need to lock the transfer -+ * sizes to 8bit to avoid making the state engine on the 2026x cards -+ * barf. -+ */ -+ -+static void pdc2026x_dev_config(struct ata_port *ap, struct ata_device *adev) -+{ -+ /* We cannot blindly set 256 as the core code may already -+ have picked a lower limit */ -+ -+ if(ap->host->max_sectors > 256) { -+ ap->host->max_sectors = 256; -+ ap->host->hostt->max_sectors = 256; -+ } -+ adev->flags |= ATA_DFLAG_LOCK_SECTORS; -+} -+ -+static struct scsi_host_template pdc_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 pdc2024x_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = pdc_set_piomode, -+ .set_dmamode = pdc_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 = pdc2024x_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 pdc2026x_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = pdc_set_piomode, -+ .set_dmamode = pdc_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 = pdc2026x_dev_config, -+ -+ .phy_reset = pdc2026x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = pdc2026x_bmdma_start, -+ .bmdma_stop = pdc2026x_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = pdc2026x_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 pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info[3] = { -+ { -+ .sht = &pdc_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA2, -+ .port_ops = &pdc2024x_port_ops -+ }, -+ { -+ .sht = &pdc_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA4, -+ .port_ops = &pdc2026x_port_ops -+ }, -+ { -+ .sht = &pdc_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &pdc2026x_port_ops -+ } -+ -+ }; -+ static struct ata_port_info *port_info[2]; -+ -+ port_info[0] = port_info[1] = &info[id->driver_data]; -+ -+ if (dev->device == PCI_DEVICE_ID_PROMISE_20265) { -+ struct pci_dev *bridge = dev->bus->self; -+ /* Don't grab anything behind a Promise I2O RAID */ -+ if (bridge && bridge->vendor == PCI_VENDOR_ID_INTEL) { -+ if( bridge->device == PCI_DEVICE_ID_INTEL_I960) -+ return -ENODEV; -+ if( bridge->device == PCI_DEVICE_ID_INTEL_I960RM) -+ return -ENODEV; -+ } -+ } -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id pdc[] = { -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { 0, }, -+}; -+ -+static struct pci_driver pdc_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = pdc, -+ .probe = pdc_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init pdc_init(void) -+{ -+ return pci_register_driver(&pdc_pci_driver); -+} -+ -+ -+static void __exit pdc_exit(void) -+{ -+ pci_unregister_driver(&pdc_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, pdc); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(pdc_init); -+module_exit(pdc_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_qdi.c linux-2.6.16-rc4/drivers/scsi/pata_qdi.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_qdi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_qdi.c 2006-02-15 15:08:22.000000000 +0000 -@@ -0,0 +1,370 @@ -+/* -+ * 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.2" -+ -+#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, 30303, 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, 30303, 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, struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) -+{ -+ int slop = buflen & 3; -+ -+ if (ata_id_has_dword_io(adev->id)) { -+ 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); -+ } -+ } -+ } else -+ ata_pio_data_xfer(ap, adev, buf, buflen, write_data); -+} -+ -+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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_radisys.c linux-2.6.16-rc4/drivers/scsi/pata_radisys.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_radisys.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_radisys.c 2006-02-17 15:31:12.000000000 +0000 -@@ -0,0 +1,321 @@ -+/* -+ * pata_radisys.c - Intel PATA/SATA controllers -+ * -+ * (C) 2006 Red Hat <alan@redhat.com> -+ * -+ * Some parts based on ata_piix.c by Jeff Garzik and others. -+ * -+ * A PIIX relative, this device has a single ATA channel and no -+ * slave timings, SITRE or PPE. In that sense it is a close relative -+ * of the original PIIX. It does however support UDMA 33/66 per channel -+ * although no other modes/timings. Also lacking is 32bit I/O on the ATA -+ * port. -+ */ -+ -+#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_radisys" -+#define DRV_VERSION "0.2" -+ -+/** -+ * radisys_pata_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void radisys_pata_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA80; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * radisys_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 radisys_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); -+ 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. The Radisys is a relative of the PIIX -+ * but not the same so be careful. -+ */ -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, /* Check me */ -+ { 0, 0 }, -+ { 1, 1 }, -+ { 2, 2 }, -+ { 3, 3 }, }; -+ -+ if (pio > 0) -+ control |= 1; /* TIME1 enable */ -+ if (ata_pio_need_iordy(adev)) -+ control |= 2; /* IE IORDY */ -+ -+ pci_read_config_word(dev, 0x40, &idetm_data); -+ -+ /* Enable IE and TIME as appropriate. Clear the other -+ drive timing bits */ -+ idetm_data &= 0xCCCC; -+ idetm_data |= (control << (4 * adev->devno)); -+ idetm_data |= (timings[pio][0] << 12) | -+ (timings[pio][1] << 8); -+ pci_write_config_word(dev, 0x40, idetm_data); -+ -+ /* Track which port is configured */ -+ ap->private_data = adev; -+} -+ -+/** -+ * radisys_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 radisys_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -+ u16 idetm_data; -+ u8 udma_enable; -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 1 }, -+ { 2, 2 }, -+ { 3, 3 }, }; -+ -+ /* -+ * MWDMA is driven by the PIO timings. We must also enable -+ * IORDY unconditionally. -+ */ -+ -+ pci_read_config_word(dev, 0x40, &idetm_data); -+ pci_read_config_byte(dev, 0x48, &udma_enable); -+ -+ if (adev->dma_mode < XFER_UDMA_0) { -+ unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0; -+ const unsigned int needed_pio[3] = { -+ XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 -+ }; -+ int pio = needed_pio[mwdma] - XFER_PIO_0; -+ int control = 3; /* IORDY|TIME0 */ -+ -+ /* If the drive MWDMA is faster than it can do PIO then -+ we must force PIO0 for PIO cycles. */ -+ -+ if (adev->pio_mode < needed_pio[mwdma]) -+ control = 1; -+ -+ /* Mask out the relevant control and timing bits we will load. Also -+ clear the other drive TIME register as a precaution */ -+ -+ idetm_data &= 0xCCCC; -+ idetm_data |= control << (4 * adev->devno); -+ idetm_data |= (timings[pio][0] << 12) | (timings[pio][1] << 8); -+ -+ udma_enable &= ~(1 << adev->devno); -+ } else { -+ u8 udma_mode; -+ -+ /* UDMA66 on. It isn't clear from the documentation whether -+ UDMA 33 and 66 are switchable via register 0x4A */ -+ -+ pci_read_config_byte(dev, 0x4A, &udma_mode); -+ -+ if (adev->xfer_mode == XFER_UDMA_2) -+ udma_mode &= ~ (1 << adev->devno); -+ else /* UDMA 4 */ -+ udma_mode |= (1 << adev->devno); -+ -+ pci_write_config_byte(dev, 0x4A, udma_mode); -+ -+ udma_enable |= (1 << adev->devno); -+ } -+ pci_write_config_word(dev, 0x40, idetm_data); -+ pci_write_config_byte(dev, 0x48, udma_enable); -+ -+ /* Track which port is configured */ -+ ap->private_data = adev; -+} -+ -+/** -+ * radisys_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 radisys_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) { -+ /* UDMA timing is not shared */ -+ if (adev->dma_mode < XFER_UDMA_0) { -+ if (adev->dma_mode) -+ radisys_set_dmamode(ap, adev); -+ else if (adev->pio_mode) -+ radisys_set_piomode(ap, adev); -+ } -+ } -+ return ata_qc_issue_prot(qc); -+} -+ -+ -+static struct scsi_host_template radisys_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 radisys_pata_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = radisys_set_piomode, -+ .set_dmamode = radisys_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 = radisys_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 = radisys_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, -+}; -+ -+ -+/** -+ * radisys_init_one - Register PIIX ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in radisys_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 radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ static struct ata_port_info info = { -+ .sht = &radisys_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma1-2 */ -+ .udma_mask = 0x14, /* UDMA33/66 only */ -+ .port_ops = &radisys_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 radisys_pci_tbl[] = { -+ { 0x1331, 0x8201, PCI_ANY_ID, PCI_ANY_ID, }, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver radisys_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = radisys_pci_tbl, -+ .probe = radisys_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init radisys_init(void) -+{ -+ return pci_register_driver(&radisys_pci_driver); -+} -+ -+static void __exit radisys_exit(void) -+{ -+ pci_unregister_driver(&radisys_pci_driver); -+} -+ -+ -+module_init(radisys_init); -+module_exit(radisys_exit); -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("SCSI low-level driver for Radisys R82600 controllers"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, radisys_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_rz1000.c linux-2.6.16-rc4/drivers/scsi/pata_rz1000.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_rz1000.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_rz1000.c 2006-02-16 15:38:18.000000000 +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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sc1200.c linux-2.6.16-rc4/drivers/scsi/pata_sc1200.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sc1200.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_sc1200.c 2006-02-16 15:46:11.000000000 +0000 -@@ -0,0 +1,286 @@ -+/* -+ * 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.2" -+ -+#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. -+ */ -+ -+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); -+} -+ -+/** -+ * sc1200_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. Specifically we have a problem that there is only -+ * one MWDMA/UDMA bit. -+ */ -+ -+static int sc1200_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ struct ata_device *prev = ap->private_data; -+ -+ /* See if the DMA settings could be wrong */ -+ if (adev->dma_mode != 0 && adev != prev && prev != NULL) { -+ /* Maybe, but do the channels match MWDMA/UDMA ? */ -+ if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) || -+ (adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0)) -+ /* Switch the mode bits */ -+ sc1200_set_dmamode(ap, adev); -+ } -+ -+ return ata_qc_issue_prot(qc); -+} -+ -+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 = { -+ .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 = sc1200_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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_serverworks.c linux-2.6.16-rc4/drivers/scsi/pata_serverworks.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_serverworks.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_serverworks.c 2006-02-16 15:37:31.000000000 +0000 -@@ -0,0 +1,586 @@ -+/* -+ * 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); -+ } -+ } 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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sil680.c linux-2.6.16-rc4/drivers/scsi/pata_sil680.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sil680.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_sil680.c 2006-02-16 15:28:00.000000000 +0000 -@@ -0,0 +1,368 @@ -+/* -+ * 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. -+ */ -+ -+#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.2.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 we must pick the lowest -+ * mode for command work. -+ */ -+ -+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; -+ int lowest_pio = pio; -+ u16 reg; -+ -+ struct ata_device *pair = ata_dev_pair(ap, adev); -+ -+ if (pair != NULL) { -+ if (adev->pio_mode > pair->pio_mode) -+ lowest_pio = pair->pio_mode - XFER_PIO_0; -+ } -+ -+ pci_write_config_word(pdev, addr, speed_p[pio]); -+ pci_write_config_word(pdev, tfaddr, speed_t[lowest_pio]); -+ -+ pci_read_config_word(pdev, tfaddr-2, ®); -+ reg &= ~0x0200; /* Clear IORDY */ -+ if (ata_pio_need_iordy(adev)) -+ 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. -+ */ -+ -+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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sis.c linux-2.6.16-rc4/drivers/scsi/pata_sis.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sis.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_sis.c 2006-02-16 15:36:13.000000000 +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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sl82c105.c linux-2.6.16-rc4/drivers/scsi/pata_sl82c105.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sl82c105.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_sl82c105.c 2006-02-16 15:36:32.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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_triflex.c linux-2.6.16-rc4/drivers/scsi/pata_triflex.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_triflex.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_triflex.c 2006-02-16 15:36:23.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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_via.c linux-2.6.16-rc4/drivers/scsi/pata_via.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_via.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_via.c 2006-02-16 15:28:17.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.4" -+ -+/* -+ * 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 = ata_dev_pair(ap, adev); -+ 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 (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 --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 -@@ -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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_nv.c linux-2.6.16-rc4/drivers/scsi/sata_nv.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_nv.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_promise.c linux-2.6.16-rc4/drivers/scsi/sata_promise.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_promise.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_qstor.c linux-2.6.16-rc4/drivers/scsi/sata_qstor.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_qstor.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sil24.c linux-2.6.16-rc4/drivers/scsi/sata_sil24.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sil24.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sil.c linux-2.6.16-rc4/drivers/scsi/sata_sil.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sil.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_sil.c 2006-02-14 17:23:28.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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sis.c linux-2.6.16-rc4/drivers/scsi/sata_sis.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sis.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_svw.c linux-2.6.16-rc4/drivers/scsi/sata_svw.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_svw.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sx4.c linux-2.6.16-rc4/drivers/scsi/sata_sx4.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sx4.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_uli.c linux-2.6.16-rc4/drivers/scsi/sata_uli.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_uli.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_via.c linux-2.6.16-rc4/drivers/scsi/sata_via.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_via.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_vsc.c linux-2.6.16-rc4/drivers/scsi/sata_vsc.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_vsc.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_vsc.c 2006-02-20 11:28:11.000000000 +0000 -@@ -280,6 +280,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 --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/include/linux/ata.h linux-2.6.16-rc4/include/linux/ata.h ---- linux.vanilla-2.6.16-rc4/include/linux/ata.h 2006-02-20 11:22:26.000000000 +0000 -+++ linux-2.6.16-rc4/include/linux/ata.h 2006-02-15 14:39:41.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,18 +249,22 @@ - }; - - #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)) - #define ata_id_has_dma(id) ((id)[49] & (1 << 8)) - #define ata_id_removeable(id) ((id)[0] & (1 << 7)) -+#define ata_id_has_dword_io(id) ((id)[50] & (1 << 0)) - #define ata_id_u32(id,n) \ - (((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)])) - #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-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 */ - #undef ATA_NDEBUG /* define to disable quick runtime checks */ --#undef ATA_ENABLE_PATA /* define to enable PATA support in some -+#define ATA_ENABLE_PATA /* define to enable PATA support in some - * low-level drivers */ - #undef ATAPI_ENABLE_DMADIR /* enables ATAPI DMADIR bridge support */ - -@@ -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 *, struct ata_device *, 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, struct ata_device *adev, unsigned char *buf, -+ unsigned int buflen, int write_data); -+extern void ata_pio_data_xfer(struct ata_port *ap, struct ata_device *adev, unsigned char *buf, -+ unsigned int buflen, int write_data); -+extern void ata_mmio_data_xfer_noirq(struct ata_port *ap, struct ata_device *adev, unsigned char *buf, -+ unsigned int buflen, int do_write); -+extern void ata_pio_data_xfer_noirq(struct ata_port *ap, struct ata_device *adev, 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 *)); -@@ -498,6 +521,8 @@ - struct block_device *bdev, - sector_t capacity, int geom[]); - extern int ata_scsi_slave_config(struct scsi_device *sdev); -+extern struct ata_device *ata_dev_pair(struct ata_port *ap, -+ struct ata_device *adev); - - /* - * Timing helpers |