From f88c480dac88a754f84e943cb5539d59cda3c089 Mon Sep 17 00:00:00 2001 From: sonic zhang Date: Tue, 27 Nov 2007 12:47:39 +0800 Subject: [PATCH 1/8] Set proper ATA UDMA mode for bf548 according to system clock. UDMA Mode - Frequency compatibility UDMA5 - 100 MB/s - SCLK = 133 MHz UDMA4 - 66 MB/s - SCLK >= 80 MHz UDMA3 - 44.4 MB/s - SCLK >= 50 MHz UDMA2 - 33 MB/s - SCLK >= 40 MHz Signed-off-by: Sonic Zhang Signed-off-by: Jeff Garzik --- drivers/ata/pata_bf54x.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 81db405a5445..088a41f4e656 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1489,6 +1489,8 @@ static int __devinit bfin_atapi_probe(struct platform_device *pdev) int board_idx = 0; struct resource *res; struct ata_host *host; + unsigned int fsclk = get_sclk(); + int udma_mode = 5; const struct ata_port_info *ppi[] = { &bfin_port_info[board_idx], NULL }; @@ -1507,6 +1509,11 @@ static int __devinit bfin_atapi_probe(struct platform_device *pdev) if (res == NULL) return -EINVAL; + while (bfin_port_info[board_idx].udma_mask>0 && udma_fsclk[udma_mode] > fsclk) { + udma_mode--; + bfin_port_info[board_idx].udma_mask >>= 1; + } + /* * Now that that's out of the way, wire up the port.. */ From 2d79ab8fd7a7bf3a45d0e948ae27b3dd95ce95ea Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Tue, 27 Nov 2007 17:26:08 +0200 Subject: [PATCH 2/8] sata_mv: fix compilation error when enabling DEBUG use sstatus instead status. Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index a43f64d2775b..97c3e116977e 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -2170,7 +2170,7 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class, mv_scr_read(ap, SCR_ERROR, &serror); mv_scr_read(ap, SCR_CONTROL, &scontrol); DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " - "SCtrl 0x%08x\n", status, serror, scontrol); + "SCtrl 0x%08x\n", sstatus, serror, scontrol); } #endif From 1c20a493caa30c5d47a394f9dbd86e6282323db9 Mon Sep 17 00:00:00 2001 From: Kristoffer Nyborg Gregertsen Date: Thu, 29 Nov 2007 12:01:51 +0100 Subject: [PATCH 3/8] Several fixes for the AVR32 PATA driver Several fixes for the AVR32 PATA driver: * Updated to use new AVR32 SMC timing API. This removes the need for "magic" constants in signal timing. * Removed the ATA_FLAG_PIO_POLLING, the driver should use interrupts. * Removed .port_disable and .irq_ack as these are no longer needed. * Improved some comments. Signed-off-by: Kristoffer Nyborg Gregertsen Signed-off-by: Jeff Garzik --- drivers/ata/pata_at32.c | 61 ++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c index bb250a48e27c..67e574de31e8 100644 --- a/drivers/ata/pata_at32.c +++ b/drivers/ata/pata_at32.c @@ -28,7 +28,7 @@ #include #define DRV_NAME "pata_at32" -#define DRV_VERSION "0.0.2" +#define DRV_VERSION "0.0.3" /* * CompactFlash controller memory layout relative to the base address: @@ -64,6 +64,8 @@ * Mode 2 | 8.3 | 240 ns | 0x07 * Mode 3 | 11.1 | 180 ns | 0x0f * Mode 4 | 16.7 | 120 ns | 0x1f + * + * Alter PIO_MASK below according to table to set maximal PIO mode. */ #define PIO_MASK (0x1f) @@ -85,36 +87,40 @@ struct at32_ide_info { */ static int pata_at32_setup_timing(struct device *dev, struct at32_ide_info *info, - const struct ata_timing *timing) + const struct ata_timing *ata) { - /* These two values are found through testing */ - const int min_recover = 25; - const int ncs_hold = 15; - struct smc_config *smc = &info->smc; + struct smc_timing timing; int active; int recover; + memset(&timing, 0, sizeof(struct smc_timing)); + /* Total cycle time */ - smc->read_cycle = timing->cyc8b; + timing.read_cycle = ata->cyc8b; /* DIOR <= CFIOR timings */ - smc->nrd_setup = timing->setup; - smc->nrd_pulse = timing->act8b; + timing.nrd_setup = ata->setup; + timing.nrd_pulse = ata->act8b; + timing.nrd_recover = ata->rec8b; + + /* Convert nanosecond timing to clock cycles */ + smc_set_timing(smc, &timing); - /* Compute recover, extend total cycle if needed */ - active = smc->nrd_setup + smc->nrd_pulse; + /* Add one extra cycle setup due to signal ring */ + smc->nrd_setup = smc->nrd_setup + 1; + + active = smc->nrd_setup + smc->nrd_pulse; recover = smc->read_cycle - active; - if (recover < min_recover) { - smc->read_cycle = active + min_recover; - recover = min_recover; - } + /* Need at least two cycles recovery */ + if (recover < 2) + smc->read_cycle = active + 2; /* (CS0, CS1, DIR, OE) <= (CFCE1, CFCE2, CFRNW, NCSX) timings */ - smc->ncs_read_setup = 0; - smc->ncs_read_pulse = active + ncs_hold; + smc->ncs_read_setup = 1; + smc->ncs_read_pulse = smc->read_cycle - 2; /* Write timings same as read timings */ smc->write_cycle = smc->read_cycle; @@ -123,11 +129,13 @@ static int pata_at32_setup_timing(struct device *dev, smc->ncs_write_setup = smc->ncs_read_setup; smc->ncs_write_pulse = smc->ncs_read_pulse; - /* Do some debugging output */ - dev_dbg(dev, "SMC: C=%d S=%d P=%d R=%d NCSS=%d NCSP=%d NCSR=%d\n", + /* Do some debugging output of ATA and SMC timings */ + dev_dbg(dev, "ATA: C=%d S=%d P=%d R=%d\n", + ata->cyc8b, ata->setup, ata->act8b, ata->rec8b); + + dev_dbg(dev, "SMC: C=%d S=%d P=%d NS=%d NP=%d\n", smc->read_cycle, smc->nrd_setup, smc->nrd_pulse, - recover, smc->ncs_read_setup, smc->ncs_read_pulse, - smc->read_cycle - smc->ncs_read_pulse); + smc->ncs_read_setup, smc->ncs_read_pulse); /* Finally, configure the SMC */ return smc_set_configuration(info->cs, smc); @@ -182,7 +190,6 @@ static struct scsi_host_template at32_sht = { }; static struct ata_port_operations at32_port_ops = { - .port_disable = ata_port_disable, .set_piomode = pata_at32_set_piomode, .tf_load = ata_tf_load, .tf_read = ata_tf_read, @@ -203,7 +210,6 @@ static struct ata_port_operations at32_port_ops = { .irq_clear = pata_at32_irq_clear, .irq_on = ata_irq_on, - .irq_ack = ata_irq_ack, .port_start = ata_sff_port_start, }; @@ -223,8 +229,7 @@ static int __init pata_at32_init_one(struct device *dev, /* Setup ATA bindings */ ap->ops = &at32_port_ops; ap->pio_mask = PIO_MASK; - ap->flags = ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS - | ATA_FLAG_PIO_POLLING; + ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS; /* * Since all 8-bit taskfile transfers has to go on the lower @@ -357,12 +362,12 @@ static int __init pata_at32_probe(struct platform_device *pdev) info->smc.tdf_mode = 0; /* TDF optimization disabled */ info->smc.tdf_cycles = 0; /* No TDF wait cycles */ - /* Setup ATA timing */ + /* Setup SMC to ATA timing */ ret = pata_at32_setup_timing(dev, info, &initial_timing); if (ret) goto err_setup_timing; - /* Setup ATA addresses */ + /* Map ATA address space */ ret = -ENOMEM; info->ide_addr = devm_ioremap(dev, info->res_ide.start, 16); info->alt_addr = devm_ioremap(dev, info->res_alt.start, 16); @@ -373,7 +378,7 @@ static int __init pata_at32_probe(struct platform_device *pdev) pata_at32_debug_bus(dev, info); #endif - /* Register ATA device */ + /* Setup and register ATA device */ ret = pata_at32_init_one(dev, info); if (ret) goto err_ata_device; From abb6a88974a8c92b049eddf37685899c4021cf0a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 28 Nov 2007 23:16:09 +0900 Subject: [PATCH 4/8] libata: report protocol and full CDB on error Protocol and CDB allocation size field are important in determining what went wrong with ATAPI commands. Report them on failure. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 42 ++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 0dac69db1fdf..e6605f038647 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1850,30 +1850,54 @@ static void ata_eh_link_report(struct ata_link *link) ehc->i.serror & SERR_DEV_XCHG ? "DevExch " : ""); for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { - static const char *dma_str[] = { - [DMA_BIDIRECTIONAL] = "bidi", - [DMA_TO_DEVICE] = "out", - [DMA_FROM_DEVICE] = "in", - [DMA_NONE] = "", - }; struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf; + const u8 *cdb = qc->cdb; + char data_buf[20] = ""; + char cdb_buf[70] = ""; if (!(qc->flags & ATA_QCFLAG_FAILED) || qc->dev->link != link || !qc->err_mask) continue; + if (qc->dma_dir != DMA_NONE) { + static const char *dma_str[] = { + [DMA_BIDIRECTIONAL] = "bidi", + [DMA_TO_DEVICE] = "out", + [DMA_FROM_DEVICE] = "in", + }; + static const char *prot_str[] = { + [ATA_PROT_PIO] = "pio", + [ATA_PROT_DMA] = "dma", + [ATA_PROT_NCQ] = "ncq", + [ATA_PROT_ATAPI] = "pio", + [ATA_PROT_ATAPI_DMA] = "dma", + }; + + snprintf(data_buf, sizeof(data_buf), " %s %u %s", + prot_str[qc->tf.protocol], qc->nbytes, + dma_str[qc->dma_dir]); + } + + if (is_atapi_taskfile(&qc->tf)) + snprintf(cdb_buf, sizeof(cdb_buf), + "cdb %02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x\n ", + cdb[0], cdb[1], cdb[2], cdb[3], + cdb[4], cdb[5], cdb[6], cdb[7], + cdb[8], cdb[9], cdb[10], cdb[11], + cdb[12], cdb[13], cdb[14], cdb[15]); + ata_dev_printk(qc->dev, KERN_ERR, "cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " - "tag %d cdb 0x%x data %u %s\n " + "tag %d%s\n %s" "res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " "Emask 0x%x (%s)%s\n", cmd->command, cmd->feature, cmd->nsect, cmd->lbal, cmd->lbam, cmd->lbah, cmd->hob_feature, cmd->hob_nsect, cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah, - cmd->device, qc->tag, qc->cdb[0], qc->nbytes, - dma_str[qc->dma_dir], + cmd->device, qc->tag, data_buf, cdb_buf, res->command, res->feature, res->nsect, res->lbal, res->lbam, res->lbah, res->hob_feature, res->hob_nsect, From e9f3340673c1da32041f2a282b166c72cd78632e Mon Sep 17 00:00:00 2001 From: Peter Missel Date: Tue, 27 Nov 2007 18:04:42 +0100 Subject: [PATCH 5/8] libata: More IVB horkage from TSST libata: Add more TSST (Samsung/Toshiba) IDE drives with broken cable detection validation bits. signed-off-by: Peter Missel (peter.missel@onlinehome.de) Acked-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 33f06277b3be..53d11017a5c3 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4185,6 +4185,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* Devices which get the IVB wrong */ { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, }, { "TSSTcorp CDDVDW SH-S202J", "SB00", ATA_HORKAGE_IVB, }, + { "TSSTcorp CDDVDW SH-S202J", "SB01", ATA_HORKAGE_IVB, }, + { "TSSTcorp CDDVDW SH-S202N", "SB00", ATA_HORKAGE_IVB, }, + { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, }, /* End Marker */ { } From 04d86d6fc0477f217d60667adfc26f1f56264cc9 Mon Sep 17 00:00:00 2001 From: Peter Schwenke Date: Fri, 30 Nov 2007 15:28:29 +0900 Subject: [PATCH 6/8] ata_piix: add more toshiba laptops to broken suspend list Add more toshiba laptops to broken suspend list. This is from OSDL bugzilla bug 7780. tj: re-formatted patch and added description and SOB. Signed-off-by: Peter Schwenke Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 483269db2c7d..b538e1d22bf2 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -966,6 +966,13 @@ static int piix_broken_suspend(void) DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M3"), }, }, + { + .ident = "TECRA M3", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Tecra M3"), + }, + }, { .ident = "TECRA M5", .matches = { @@ -980,6 +987,20 @@ static int piix_broken_suspend(void) DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M7"), }, }, + { + .ident = "TECRA A8", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A8"), + }, + }, + { + .ident = "Satellite R25", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite R25"), + }, + }, { .ident = "Satellite U200", .matches = { @@ -987,6 +1008,13 @@ static int piix_broken_suspend(void) DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U200"), }, }, + { + .ident = "Satellite U200", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE U200"), + }, + }, { .ident = "Satellite Pro U200", .matches = { From 0f9fe9b7148f95f018ae2c97f7fa1a35364ea785 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 30 Nov 2007 15:23:16 +0000 Subject: [PATCH 7/8] libata: Fix early use of port printk. (Was Re: ata4294967295: failed to start port (errno=-19)) On Fri, 30 Nov 2007 14:34:11 +0200 (EET) Meelis Roos wrote: > > Can you stick a stack trace in at that point ? That would help diagnose > > it a great deal quicker. > > Finally done - found out hard way that BUG() is too bad and > dump_st5ack() suits me better. Thanks. This should fix the real cause, and also allow for port start to fail politely with -ENODEV. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 53d11017a5c3..b514a80f1370 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6967,12 +6967,11 @@ int ata_host_start(struct ata_host *host) if (ap->ops->port_start) { rc = ap->ops->port_start(ap); if (rc) { - ata_port_printk(ap, KERN_ERR, "failed to " - "start port (errno=%d)\n", rc); + if (rc != -ENODEV) + dev_printk(KERN_ERR, host->dev, "failed to start port %d (errno=%d)\n", i, rc); goto err_out; } } - ata_eh_freeze_port(ap); } From 02a121da5a53d415b6596bc19cc6999d295d32a4 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Sat, 1 Dec 2007 13:07:22 -0500 Subject: [PATCH 8/8] sata_mv: Fix broken Marvell 7042 support. sata_mv: Fix broken Marvell 7042 support. The Marvell 7042 chip is more or less the same as the 6042 internally, but sports a PCIe bus. Despite having identical SATA cores, the 7042 does differ from its PCI bus counterparts in placment and layout of certain bus related registers. This patch fixes sata_mv to distinguish between the PCI bus registers of earlier chips, and the PCIe bus registers of the 7042. Specifically, move the offsets and bit patterns for the PCI/PCIe interrupt cause/mask registers into the struct mv_host_priv, as these values differ between the 6xxx and 7xxx series chips. This fixes the driver to not access reserved PCI addresses, and prevents the lockups reported in linux-2.6.24 with 7042 boards. Also add a new PCI ID for the Highpoint 2300 7042-based board that I'm using for testing this stuff here. Tested with Marvell 6081 + 7042 chips, on x86 & x86_64. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 62 +++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 97c3e116977e..8d864e5e97ed 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -164,10 +164,14 @@ enum { MV_PCI_ERR_ATTRIBUTE = 0x1d48, MV_PCI_ERR_COMMAND = 0x1d50, - PCI_IRQ_CAUSE_OFS = 0x1d58, - PCI_IRQ_MASK_OFS = 0x1d5c, + PCI_IRQ_CAUSE_OFS = 0x1d58, + PCI_IRQ_MASK_OFS = 0x1d5c, PCI_UNMASK_ALL_IRQS = 0x7fffff, /* bits 22-0 */ + PCIE_IRQ_CAUSE_OFS = 0x1900, + PCIE_IRQ_MASK_OFS = 0x1910, + PCIE_UNMASK_ALL_IRQS = 0x70a, /* assorted bits */ + HC_MAIN_IRQ_CAUSE_OFS = 0x1d60, HC_MAIN_IRQ_MASK_OFS = 0x1d64, PORT0_ERR = (1 << 0), /* shift by port # */ @@ -303,6 +307,7 @@ enum { MV_HP_GEN_I = (1 << 6), /* Generation I: 50xx */ MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */ MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ + MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */ /* Port private flags (pp_flags) */ MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ @@ -388,7 +393,15 @@ struct mv_port_signal { u32 pre; }; -struct mv_host_priv; +struct mv_host_priv { + u32 hp_flags; + struct mv_port_signal signal[8]; + const struct mv_hw_ops *ops; + u32 irq_cause_ofs; + u32 irq_mask_ofs; + u32 unmask_all_irqs; +}; + struct mv_hw_ops { void (*phy_errata)(struct mv_host_priv *hpriv, void __iomem *mmio, unsigned int port); @@ -401,12 +414,6 @@ struct mv_hw_ops { void (*reset_bus)(struct pci_dev *pdev, void __iomem *mmio); }; -struct mv_host_priv { - u32 hp_flags; - struct mv_port_signal signal[8]; - const struct mv_hw_ops *ops; -}; - static void mv_irq_clear(struct ata_port *ap); static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val); static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); @@ -631,11 +638,13 @@ static const struct pci_device_id mv_pci_tbl[] = { /* Adaptec 1430SA */ { PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 }, - { PCI_VDEVICE(TTI, 0x2310), chip_7042 }, - - /* add Marvell 7042 support */ + /* Marvell 7042 support */ { PCI_VDEVICE(MARVELL, 0x7042), chip_7042 }, + /* Highpoint RocketRAID PCIe series */ + { PCI_VDEVICE(TTI, 0x2300), chip_7042 }, + { PCI_VDEVICE(TTI, 0x2310), chip_7042 }, + { } /* terminate list */ }; @@ -1648,13 +1657,14 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) static void mv_pci_error(struct ata_host *host, void __iomem *mmio) { + struct mv_host_priv *hpriv = host->private_data; struct ata_port *ap; struct ata_queued_cmd *qc; struct ata_eh_info *ehi; unsigned int i, err_mask, printed = 0; u32 err_cause; - err_cause = readl(mmio + PCI_IRQ_CAUSE_OFS); + err_cause = readl(mmio + hpriv->irq_cause_ofs); dev_printk(KERN_ERR, host->dev, "PCI ERROR; PCI IRQ cause=0x%08x\n", err_cause); @@ -1662,7 +1672,7 @@ static void mv_pci_error(struct ata_host *host, void __iomem *mmio) DPRINTK("All regs @ PCI error\n"); mv_dump_all_regs(mmio, -1, to_pci_dev(host->dev)); - writelfl(0, mmio + PCI_IRQ_CAUSE_OFS); + writelfl(0, mmio + hpriv->irq_cause_ofs); for (i = 0; i < host->n_ports; i++) { ap = host->ports[i]; @@ -1926,6 +1936,8 @@ static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, #define ZERO(reg) writel(0, mmio + (reg)) static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio) { + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct mv_host_priv *hpriv = host->private_data; u32 tmp; tmp = readl(mmio + MV_PCI_MODE); @@ -1937,8 +1949,8 @@ static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio) writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT); ZERO(HC_MAIN_IRQ_MASK_OFS); ZERO(MV_PCI_SERR_MASK); - ZERO(PCI_IRQ_CAUSE_OFS); - ZERO(PCI_IRQ_MASK_OFS); + ZERO(hpriv->irq_cause_ofs); + ZERO(hpriv->irq_mask_ofs); ZERO(MV_PCI_ERR_LOW_ADDRESS); ZERO(MV_PCI_ERR_HIGH_ADDRESS); ZERO(MV_PCI_ERR_ATTRIBUTE); @@ -2490,6 +2502,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) break; case chip_7042: + hp_flags |= MV_HP_PCIE; case chip_6042: hpriv->ops = &mv6xxx_ops; hp_flags |= MV_HP_GEN_IIE; @@ -2516,6 +2529,15 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) } hpriv->hp_flags = hp_flags; + if (hp_flags & MV_HP_PCIE) { + hpriv->irq_cause_ofs = PCIE_IRQ_CAUSE_OFS; + hpriv->irq_mask_ofs = PCIE_IRQ_MASK_OFS; + hpriv->unmask_all_irqs = PCIE_UNMASK_ALL_IRQS; + } else { + hpriv->irq_cause_ofs = PCI_IRQ_CAUSE_OFS; + hpriv->irq_mask_ofs = PCI_IRQ_MASK_OFS; + hpriv->unmask_all_irqs = PCI_UNMASK_ALL_IRQS; + } return 0; } @@ -2595,10 +2617,10 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) } /* Clear any currently outstanding host interrupt conditions */ - writelfl(0, mmio + PCI_IRQ_CAUSE_OFS); + writelfl(0, mmio + hpriv->irq_cause_ofs); /* and unmask interrupt generation for host regs */ - writelfl(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS); + writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); if (IS_GEN_I(hpriv)) writelfl(~HC_MAIN_MASKED_IRQS_5, mmio + HC_MAIN_IRQ_MASK_OFS); @@ -2609,8 +2631,8 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) "PCI int cause/mask=0x%08x/0x%08x\n", readl(mmio + HC_MAIN_IRQ_CAUSE_OFS), readl(mmio + HC_MAIN_IRQ_MASK_OFS), - readl(mmio + PCI_IRQ_CAUSE_OFS), - readl(mmio + PCI_IRQ_MASK_OFS)); + readl(mmio + hpriv->irq_cause_ofs), + readl(mmio + hpriv->irq_mask_ofs)); done: return rc;