diff options
Diffstat (limited to 'drivers/ata/sata_mv.c')
| -rw-r--r-- | drivers/ata/sata_mv.c | 243 |
1 files changed, 117 insertions, 126 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 9d86203e1e7a..ffb396f61731 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -579,7 +579,7 @@ struct mv_hw_ops { void (*enable_leds)(struct mv_host_priv *hpriv, void __iomem *mmio); void (*read_preamp)(struct mv_host_priv *hpriv, int idx, void __iomem *mmio); - int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio, + int (*reset_hc)(struct ata_host *host, void __iomem *mmio, unsigned int n_hc); void (*reset_flash)(struct mv_host_priv *hpriv, void __iomem *mmio); void (*reset_bus)(struct ata_host *host, void __iomem *mmio); @@ -606,7 +606,7 @@ static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, void __iomem *mmio); -static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, +static int mv5_reset_hc(struct ata_host *host, void __iomem *mmio, unsigned int n_hc); static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); static void mv5_reset_bus(struct ata_host *host, void __iomem *mmio); @@ -616,14 +616,14 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, void __iomem *mmio); -static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, +static int mv6_reset_hc(struct ata_host *host, void __iomem *mmio, unsigned int n_hc); static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); static void mv_soc_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); static void mv_soc_read_preamp(struct mv_host_priv *hpriv, int idx, void __iomem *mmio); -static int mv_soc_reset_hc(struct mv_host_priv *hpriv, +static int mv_soc_reset_hc(struct ata_host *host, void __iomem *mmio, unsigned int n_hc); static void mv_soc_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); @@ -659,21 +659,21 @@ static u8 mv_sff_check_status(struct ata_port *ap); * PRDs for 64K boundaries in mv_fill_sg(). */ #ifdef CONFIG_PCI -static struct scsi_host_template mv5_sht = { +static const struct scsi_host_template mv5_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = MV_MAX_SG_CT / 2, .dma_boundary = MV_DMA_BOUNDARY, }; #endif -static struct scsi_host_template mv6_sht = { +static const struct scsi_host_template mv6_sht = { __ATA_BASE_SHT(DRV_NAME), .can_queue = MV_MAX_Q_DEPTH - 1, .sg_tablesize = MV_MAX_SG_CT / 2, .dma_boundary = MV_DMA_BOUNDARY, - .sdev_attrs = ata_ncq_sdev_attrs, + .sdev_groups = ata_ncq_sdev_groups, .change_queue_depth = ata_scsi_change_queue_depth, - .tag_alloc_policy = BLK_TAG_ALLOC_RR, - .slave_configure = ata_scsi_slave_config + .tag_alloc_policy_rr = true, + .sdev_configure = ata_scsi_sdev_configure }; static struct ata_port_operations mv5_ops = { @@ -687,7 +687,7 @@ static struct ata_port_operations mv5_ops = { .freeze = mv_eh_freeze, .thaw = mv_eh_thaw, - .hardreset = mv_hardreset, + .reset.hardreset = mv_hardreset, .scr_read = mv5_scr_read, .scr_write = mv5_scr_write, @@ -709,10 +709,10 @@ static struct ata_port_operations mv6_ops = { .freeze = mv_eh_freeze, .thaw = mv_eh_thaw, - .hardreset = mv_hardreset, - .softreset = mv_softreset, - .pmp_hardreset = mv_pmp_hardreset, - .pmp_softreset = mv_softreset, + .reset.hardreset = mv_hardreset, + .reset.softreset = mv_softreset, + .pmp_reset.hardreset = mv_pmp_hardreset, + .pmp_reset.softreset = mv_softreset, .error_handler = mv_pmp_error_handler, .scr_read = mv_scr_read, @@ -787,37 +787,6 @@ static const struct ata_port_info mv_port_info[] = { }, }; -static const struct pci_device_id mv_pci_tbl[] = { - { PCI_VDEVICE(MARVELL, 0x5040), chip_504x }, - { PCI_VDEVICE(MARVELL, 0x5041), chip_504x }, - { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 }, - { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, - /* RocketRAID 1720/174x have different identifiers */ - { PCI_VDEVICE(TTI, 0x1720), chip_6042 }, - { PCI_VDEVICE(TTI, 0x1740), chip_6042 }, - { PCI_VDEVICE(TTI, 0x1742), chip_6042 }, - - { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, - { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, - { PCI_VDEVICE(MARVELL, 0x6042), chip_6042 }, - { PCI_VDEVICE(MARVELL, 0x6080), chip_608x }, - { PCI_VDEVICE(MARVELL, 0x6081), chip_608x }, - - { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x }, - - /* Adaptec 1430SA */ - { PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 }, - - /* 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 */ -}; - static const struct mv_hw_ops mv5xxx_ops = { .phy_errata = mv5_phy_errata, .enable_leds = mv5_enable_leds, @@ -1248,81 +1217,74 @@ static int mv_stop_edma(struct ata_port *ap) return err; } -#ifdef ATA_DEBUG -static void mv_dump_mem(void __iomem *start, unsigned bytes) +static void mv_dump_mem(struct device *dev, void __iomem *start, unsigned bytes) { - int b, w; + int b, w, o; + unsigned char linebuf[38]; + for (b = 0; b < bytes; ) { - DPRINTK("%p: ", start + b); - for (w = 0; b < bytes && w < 4; w++) { - printk("%08x ", readl(start + b)); + for (w = 0, o = 0; b < bytes && w < 4; w++) { + o += scnprintf(linebuf + o, sizeof(linebuf) - o, + "%08x ", readl(start + b)); b += sizeof(u32); } - printk("\n"); + dev_dbg(dev, "%s: %p: %s\n", + __func__, start + b, linebuf); } } -#endif -#if defined(ATA_DEBUG) || defined(CONFIG_PCI) + static void mv_dump_pci_cfg(struct pci_dev *pdev, unsigned bytes) { -#ifdef ATA_DEBUG - int b, w; - u32 dw; + int b, w, o; + u32 dw = 0; + unsigned char linebuf[38]; + for (b = 0; b < bytes; ) { - DPRINTK("%02x: ", b); - for (w = 0; b < bytes && w < 4; w++) { + for (w = 0, o = 0; b < bytes && w < 4; w++) { (void) pci_read_config_dword(pdev, b, &dw); - printk("%08x ", dw); + o += snprintf(linebuf + o, sizeof(linebuf) - o, + "%08x ", dw); b += sizeof(u32); } - printk("\n"); + dev_dbg(&pdev->dev, "%s: %02x: %s\n", + __func__, b, linebuf); } -#endif } -#endif -static void mv_dump_all_regs(void __iomem *mmio_base, int port, + +static void mv_dump_all_regs(void __iomem *mmio_base, struct pci_dev *pdev) { -#ifdef ATA_DEBUG - void __iomem *hc_base = mv_hc_base(mmio_base, - port >> MV_PORT_HC_SHIFT); + void __iomem *hc_base; void __iomem *port_base; int start_port, num_ports, p, start_hc, num_hcs, hc; - if (0 > port) { - start_hc = start_port = 0; - num_ports = 8; /* shld be benign for 4 port devs */ - num_hcs = 2; - } else { - start_hc = port >> MV_PORT_HC_SHIFT; - start_port = port; - num_ports = num_hcs = 1; - } - DPRINTK("All registers for port(s) %u-%u:\n", start_port, - num_ports > 1 ? num_ports - 1 : start_port); + start_hc = start_port = 0; + num_ports = 8; /* should be benign for 4 port devs */ + num_hcs = 2; + dev_dbg(&pdev->dev, + "%s: All registers for port(s) %u-%u:\n", __func__, + start_port, num_ports > 1 ? num_ports - 1 : start_port); - if (NULL != pdev) { - DPRINTK("PCI config space regs:\n"); - mv_dump_pci_cfg(pdev, 0x68); - } - DPRINTK("PCI regs:\n"); - mv_dump_mem(mmio_base+0xc00, 0x3c); - mv_dump_mem(mmio_base+0xd00, 0x34); - mv_dump_mem(mmio_base+0xf00, 0x4); - mv_dump_mem(mmio_base+0x1d00, 0x6c); + dev_dbg(&pdev->dev, "%s: PCI config space regs:\n", __func__); + mv_dump_pci_cfg(pdev, 0x68); + + dev_dbg(&pdev->dev, "%s: PCI regs:\n", __func__); + mv_dump_mem(&pdev->dev, mmio_base+0xc00, 0x3c); + mv_dump_mem(&pdev->dev, mmio_base+0xd00, 0x34); + mv_dump_mem(&pdev->dev, mmio_base+0xf00, 0x4); + mv_dump_mem(&pdev->dev, mmio_base+0x1d00, 0x6c); for (hc = start_hc; hc < start_hc + num_hcs; hc++) { hc_base = mv_hc_base(mmio_base, hc); - DPRINTK("HC regs (HC %i):\n", hc); - mv_dump_mem(hc_base, 0x1c); + dev_dbg(&pdev->dev, "%s: HC regs (HC %i):\n", __func__, hc); + mv_dump_mem(&pdev->dev, hc_base, 0x1c); } for (p = start_port; p < start_port + num_ports; p++) { port_base = mv_port_base(mmio_base, p); - DPRINTK("EDMA regs (port %i):\n", p); - mv_dump_mem(port_base, 0x54); - DPRINTK("SATA regs (port %i):\n", p); - mv_dump_mem(port_base+0x300, 0x60); + dev_dbg(&pdev->dev, "%s: EDMA regs (port %i):\n", __func__, p); + mv_dump_mem(&pdev->dev, port_base, 0x54); + dev_dbg(&pdev->dev, "%s: SATA regs (port %i):\n", __func__, p); + mv_dump_mem(&pdev->dev, port_base+0x300, 0x60); } -#endif } static unsigned int mv_scr_offset(unsigned int sc_reg_in) @@ -2962,8 +2924,8 @@ static int mv_pci_error(struct ata_host *host, void __iomem *mmio) dev_err(host->dev, "PCI ERROR; PCI IRQ cause=0x%08x\n", err_cause); - DPRINTK("All regs @ PCI error\n"); - mv_dump_all_regs(mmio, -1, to_pci_dev(host->dev)); + dev_dbg(host->dev, "%s: All regs @ PCI error\n", __func__); + mv_dump_all_regs(mmio, to_pci_dev(host->dev)); writelfl(0, mmio + hpriv->irq_cause_offset); @@ -3201,9 +3163,10 @@ static void mv5_reset_one_hc(struct mv_host_priv *hpriv, void __iomem *mmio, } #undef ZERO -static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, +static int mv5_reset_hc(struct ata_host *host, void __iomem *mmio, unsigned int n_hc) { + struct mv_host_priv *hpriv = host->private_data; unsigned int hc, port; for (hc = 0; hc < n_hc; hc++) { @@ -3262,7 +3225,7 @@ static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) * LOCKING: * Inherited from caller. */ -static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, +static int mv6_reset_hc(struct ata_host *host, void __iomem *mmio, unsigned int n_hc) { void __iomem *reg = mmio + PCI_MAIN_CMD_STS; @@ -3282,7 +3245,7 @@ static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, break; } if (!(PCI_MASTER_EMPTY & t)) { - printk(KERN_ERR DRV_NAME ": PCI master won't flush\n"); + dev_err(host->dev, "PCI master won't flush\n"); rc = 1; goto done; } @@ -3296,7 +3259,7 @@ static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, } while (!(GLOB_SFT_RST & t) && (i-- > 0)); if (!(GLOB_SFT_RST & t)) { - printk(KERN_ERR DRV_NAME ": can't set global reset\n"); + dev_err(host->dev, "can't set global reset\n"); rc = 1; goto done; } @@ -3310,7 +3273,7 @@ static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, } while ((GLOB_SFT_RST & t) && (i-- > 0)); if (GLOB_SFT_RST & t) { - printk(KERN_ERR DRV_NAME ": can't clear global reset\n"); + dev_err(host->dev, "can't clear global reset\n"); rc = 1; } done: @@ -3479,9 +3442,10 @@ static void mv_soc_reset_one_hc(struct mv_host_priv *hpriv, #undef ZERO -static int mv_soc_reset_hc(struct mv_host_priv *hpriv, +static int mv_soc_reset_hc(struct ata_host *host, void __iomem *mmio, unsigned int n_hc) { + struct mv_host_priv *hpriv = host->private_data; unsigned int port; for (port = 0; port < hpriv->n_ports; port++) @@ -3638,7 +3602,7 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, /* Workaround for errata FEr SATA#10 (part 2) */ do { - const unsigned long *timing = + const unsigned int *timing = sata_ehc_deb_timing(&link->eh_context); rc = sata_link_hardreset(link, timing, deadline + extra, @@ -3723,11 +3687,6 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) /* unmask all non-transient EDMA error interrupts */ writelfl(~EDMA_ERR_IRQ_TRANSIENT, port_mmio + EDMA_ERR_IRQ_MASK); - - VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n", - readl(port_mmio + EDMA_CFG), - readl(port_mmio + EDMA_ERR_IRQ_CAUSE), - readl(port_mmio + EDMA_ERR_IRQ_MASK)); } static unsigned int mv_in_pcix_mode(struct ata_host *host) @@ -3859,11 +3818,11 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) * * Warn the user, lest they think we're just buggy. */ - printk(KERN_WARNING DRV_NAME ": Highpoint RocketRAID" + dev_warn(&pdev->dev, "Highpoint RocketRAID" " BIOS CORRUPTS DATA on all attached drives," " regardless of if/how they are configured." " BEWARE!\n"); - printk(KERN_WARNING DRV_NAME ": For data safety, do not" + dev_warn(&pdev->dev, "For data safety, do not" " use sectors 8-9 on \"Legacy\" drives," " and avoid the final two gigabytes on" " all RocketRAID BIOS initialized drives.\n"); @@ -3896,8 +3855,8 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) break; default: - dev_err(host->dev, "BUG: invalid board index %u\n", board_idx); - return 1; + dev_alert(host->dev, "BUG: invalid board index %u\n", board_idx); + return -EINVAL; } hpriv->hp_flags = hp_flags; @@ -3954,7 +3913,7 @@ static int mv_init_host(struct ata_host *host) if (hpriv->ops->read_preamp) hpriv->ops->read_preamp(hpriv, port, mmio); - rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc); + rc = hpriv->ops->reset_hc(host, mmio, n_hc); if (rc) goto done; @@ -3972,7 +3931,7 @@ static int mv_init_host(struct ata_host *host) for (hc = 0; hc < n_hc; hc++) { void __iomem *hc_mmio = mv_hc_base(mmio, hc); - VPRINTK("HC%i: HC config=0x%08x HC IRQ cause " + dev_dbg(host->dev, "HC%i: HC config=0x%08x HC IRQ cause " "(before clear)=0x%08x\n", hc, readl(hc_mmio + HC_CFG), readl(hc_mmio + HC_IRQ_CAUSE)); @@ -4067,7 +4026,7 @@ static int mv_platform_probe(struct platform_device *pdev) /* * Simple resource validation .. */ - if (unlikely(pdev->num_resources != 2)) { + if (unlikely(pdev->num_resources != 1)) { dev_err(&pdev->dev, "invalid number of resources\n"); return -EINVAL; } @@ -4133,10 +4092,13 @@ static int mv_platform_probe(struct platform_device *pdev) hpriv->base -= SATAHC0_REG_BASE; hpriv->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(hpriv->clk)) + if (IS_ERR(hpriv->clk)) { dev_notice(&pdev->dev, "cannot get optional clkdev\n"); - else - clk_prepare_enable(hpriv->clk); + } else { + rc = clk_prepare_enable(hpriv->clk); + if (rc) + goto err; + } for (port = 0; port < n_ports; port++) { char port_number[16]; @@ -4220,7 +4182,7 @@ err: * A platform bus SATA device has been unplugged. Perform the needed * cleanup. Also called on module unload for any active devices. */ -static int mv_platform_remove(struct platform_device *pdev) +static void mv_platform_remove(struct platform_device *pdev) { struct ata_host *host = platform_get_drvdata(pdev); struct mv_host_priv *hpriv = host->private_data; @@ -4238,17 +4200,16 @@ static int mv_platform_remove(struct platform_device *pdev) } phy_power_off(hpriv->port_phys[port]); } - return 0; } #ifdef CONFIG_PM_SLEEP static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state) { struct ata_host *host = platform_get_drvdata(pdev); + if (host) - return ata_host_suspend(host, state); - else - return 0; + ata_host_suspend(host, state); + return 0; } static int mv_platform_resume(struct platform_device *pdev) @@ -4270,7 +4231,7 @@ static int mv_platform_resume(struct platform_device *pdev) /* initialize adapter */ ret = mv_init_host(host); if (ret) { - printk(KERN_ERR DRV_NAME ": Error during HW init\n"); + dev_err(&pdev->dev, "Error during HW init\n"); return ret; } ata_host_resume(host); @@ -4287,7 +4248,7 @@ static int mv_platform_resume(struct platform_device *pdev) static const struct of_device_id mv_sata_dt_ids[] = { { .compatible = "marvell,armada-370-sata", }, { .compatible = "marvell,orion-sata", }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mv_sata_dt_ids); #endif @@ -4311,6 +4272,36 @@ static int mv_pci_init_one(struct pci_dev *pdev, static int mv_pci_device_resume(struct pci_dev *pdev); #endif +static const struct pci_device_id mv_pci_tbl[] = { + { PCI_VDEVICE(MARVELL, 0x5040), chip_504x }, + { PCI_VDEVICE(MARVELL, 0x5041), chip_504x }, + { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 }, + { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, + /* RocketRAID 1720/174x have different identifiers */ + { PCI_VDEVICE(TTI, 0x1720), chip_6042 }, + { PCI_VDEVICE(TTI, 0x1740), chip_6042 }, + { PCI_VDEVICE(TTI, 0x1742), chip_6042 }, + + { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, + { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, + { PCI_VDEVICE(MARVELL, 0x6042), chip_6042 }, + { PCI_VDEVICE(MARVELL, 0x6080), chip_608x }, + { PCI_VDEVICE(MARVELL, 0x6081), chip_608x }, + + { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x }, + + /* Adaptec 1430SA */ + { PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 }, + + /* 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 */ +}; static struct pci_driver mv_pci_driver = { .name = DRV_NAME, @@ -4323,6 +4314,7 @@ static struct pci_driver mv_pci_driver = { #endif }; +MODULE_DEVICE_TABLE(pci, mv_pci_tbl); /** * mv_print_info - Dump key info to kernel log for perusal. @@ -4495,7 +4487,6 @@ static void __exit mv_exit(void) MODULE_AUTHOR("Brett Russ"); MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers"); MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(pci, mv_pci_tbl); MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:" DRV_NAME); |
