From e628dc999e43a9dd51fb6bd810772c277f934484 Mon Sep 17 00:00:00 2001 From: David Milburn Date: Tue, 14 May 2013 13:48:40 -0500 Subject: libata: export ata_port port_no attribute via /sys While registering host controller track port number based upon number of ports available on the controller, export port_no attribute through /sys. This patch is needed by udev for composing persistent links in /dev/disk/by-path. /sys/devices/pci0000:00/0000:00:1f.2/ata8/ata_port/ata8 total 0 lrwxrwxrwx. 1 root root 0 Mar 6 12:43 device -> ../../../ata8 -r--r--r--. 1 root root 4096 Mar 6 12:43 idle_irq -r--r--r--. 1 root root 4096 Mar 6 12:43 nr_pmp_links -r--r--r--. 1 root root 4096 Mar 6 12:43 port_no drwxr-xr-x. 2 root root 0 Mar 6 12:42 power lrwxrwxrwx. 1 root root 0 Mar 6 12:41 subsystem -> ../../../../../../class/ata_port -rw-r--r--. 1 root root 4096 Mar 6 12:40 uevent 1 Signed-off-by: David Milburn Signed-off-by: Tejun Heo diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 63c743b..5f7d5f9 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5636,6 +5636,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap->pflags |= ATA_PFLAG_INITIALIZING | ATA_PFLAG_FROZEN; ap->lock = &host->lock; ap->print_id = -1; + ap->local_port_no = -1; ap->host = host; ap->dev = host->dev; @@ -6126,9 +6127,10 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) kfree(host->ports[i]); /* give ports names and add SCSI hosts */ - for (i = 0; i < host->n_ports; i++) + for (i = 0; i < host->n_ports; i++) { host->ports[i]->print_id = atomic_inc_return(&ata_print_id); - + host->ports[i]->local_port_no = i + 1; + } /* Create associated sysfs transport objects */ for (i = 0; i < host->n_ports; i++) { diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index c04d393..077a856 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c @@ -37,7 +37,7 @@ #include "libata.h" #include "libata-transport.h" -#define ATA_PORT_ATTRS 2 +#define ATA_PORT_ATTRS 3 #define ATA_LINK_ATTRS 3 #define ATA_DEV_ATTRS 9 @@ -216,6 +216,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_ata_port_##name, NULL) ata_port_simple_attr(nr_pmp_links, nr_pmp_links, "%d\n", int); ata_port_simple_attr(stats.idle_irq, idle_irq, "%ld\n", unsigned long); +ata_port_simple_attr(local_port_no, port_no, "%u\n", unsigned int); static DECLARE_TRANSPORT_CLASS(ata_port_class, "ata_port", NULL, NULL, NULL); @@ -709,6 +710,7 @@ struct scsi_transport_template *ata_attach_transport(void) count = 0; SETUP_PORT_ATTRIBUTE(nr_pmp_links); SETUP_PORT_ATTRIBUTE(idle_irq); + SETUP_PORT_ATTRIBUTE(port_no); BUG_ON(count > ATA_PORT_ATTRS); i->port_attrs[count] = NULL; diff --git a/include/linux/libata.h b/include/linux/libata.h index eae7a05..47e0292 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -746,6 +746,7 @@ struct ata_port { /* Flags that change dynamically, protected by ap->lock */ unsigned int pflags; /* ATA_PFLAG_xxx */ unsigned int print_id; /* user visible unique port ID */ + unsigned int local_port_no; /* host local port num */ unsigned int port_no; /* 0 based port no. inside the host */ #ifdef CONFIG_ATA_SFF -- cgit v0.10.2 From 966fbe193f47c68e70a80ec9991098e88e7959cb Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Tue, 21 May 2013 22:30:58 +0200 Subject: libata: Add atapi_dmadir force flag Some device require DMADIR to be enabled, but are not detected as such by atapi_id_dmadir. One such example is "Asus Serillel 2" SATA-host-to-PATA-device bridge: the bridge itself requires DMADIR, even if the bridged device does not. As atapi_dmadir module parameter can cause problems with some devices (as per Tejun Heo's memory), enabling it globally may not be possible depending on the hardware. This patch adds atapi_dmadir in the form of a "force" horkage value, allowing global, per-bus and per-device control. Signed-off-by: Vincent Pelletier Signed-off-by: Tejun Heo diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index c3bfacb..489815e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1456,6 +1456,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. * dump_id: dump IDENTIFY data. + * atapi_dmadir: Enable ATAPI DMADIR bridge support + If there are multiple matching configurations changing the same attribute, the last one is used. diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5f7d5f9..c97a244 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2395,7 +2395,7 @@ int ata_dev_configure(struct ata_device *dev) cdb_intr_string = ", CDB intr"; } - if (atapi_dmadir || atapi_id_dmadir(dev->id)) { + if (atapi_dmadir || (dev->horkage & ATA_HORKAGE_ATAPI_DMADIR) || atapi_id_dmadir(dev->id)) { dev->flags |= ATA_DFLAG_DMADIR; dma_dir_string = ", DMADIR"; } @@ -6496,6 +6496,7 @@ static int __init ata_parse_force_one(char **cur, { "nosrst", .lflags = ATA_LFLAG_NO_SRST }, { "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST }, { "rstonce", .lflags = ATA_LFLAG_RST_ONCE }, + { "atapi_dmadir", .horkage_on = ATA_HORKAGE_ATAPI_DMADIR }, }; char *start = *cur, *p = *cur; char *id, *val, *endp; diff --git a/include/linux/libata.h b/include/linux/libata.h index 47e0292..c886dc87 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -399,6 +399,7 @@ enum { ATA_HORKAGE_BROKEN_FPDMA_AA = (1 << 15), /* skip AA */ ATA_HORKAGE_DUMP_ID = (1 << 16), /* dump IDENTIFY data */ ATA_HORKAGE_MAX_SEC_LBA48 = (1 << 17), /* Set max sects to 65535 */ + ATA_HORKAGE_ATAPI_DMADIR = (1 << 18), /* device requires dmadir */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ -- cgit v0.10.2 From b29900e62598cecd519c9ab2b8e4d03f8ebf702d Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Wed, 22 May 2013 08:53:48 +0900 Subject: AHCI: Make distinct names for ports in /proc/interrupts Currently all interrupts assigned to AHCI ports show up in '/proc/interrupts' as 'ahci'. This fix adds port numbers as suffixes and hence makes the descriptions distinct. Reported-by: Jan Beulich Signed-off-by: Alexander Gordeev Signed-off-by: Tejun Heo diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 251e57d..4d1c672 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1142,9 +1142,11 @@ int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis) return rc; for (i = 0; i < host->n_ports; i++) { + struct ahci_port_priv *pp = host->ports[i]->private_data; + rc = devm_request_threaded_irq(host->dev, irq + i, ahci_hw_interrupt, ahci_thread_fn, IRQF_SHARED, - dev_driver_string(host->dev), host->ports[i]); + pp->irq_desc, host->ports[i]); if (rc) goto out_free_irqs; } diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index b830e6c..05adf29 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -306,6 +306,7 @@ struct ahci_port_priv { int fbs_last_dev; /* save FBS.DEV of last FIS */ /* enclosure management info per PM slot */ struct ahci_em_priv em_priv[EM_MAX_SLOTS]; + char *irq_desc; /* desc in /proc/interrupts */ }; struct ahci_host_priv { diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 34c8216..3797a7b 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -2234,6 +2234,16 @@ static int ahci_port_start(struct ata_port *ap) if (!pp) return -ENOMEM; + if (ap->host->n_ports > 1) { + pp->irq_desc = devm_kzalloc(dev, 8, GFP_KERNEL); + if (!pp->irq_desc) { + devm_kfree(dev, pp); + return -ENOMEM; + } + snprintf(pp->irq_desc, 8, + "%s%d", dev_driver_string(dev), ap->port_no); + } + /* check FBS capability */ if ((hpriv->cap & HOST_CAP_FBS) && sata_pmp_supported(ap)) { void __iomem *port_mmio = ahci_port_base(ap); -- cgit v0.10.2 From d89995db5f238e618389604b848b431da240eb69 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 May 2013 19:41:21 +0900 Subject: ata: use platform_{get,set}_drvdata() Use the wrapper functions for getting and setting the driver data using platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev, so we can directly pass a struct platform_device. Also, unnecessary dev_set_drvdata() is removed, because the driver core clears the driver data to NULL after device_release or on probe failure. Signed-off-by: Jingoo Han Signed-off-by: Tejun Heo diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 7638121..848ed32 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -908,7 +908,7 @@ free_clk: static int arasan_cf_remove(struct platform_device *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = platform_get_drvdata(pdev); struct arasan_cf_dev *acdev = host->ports[0]->private_data; ata_host_detach(host); diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index 033f3f4..5364f97 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c @@ -422,7 +422,7 @@ err_put: static int pata_at91_remove(struct platform_device *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = platform_get_drvdata(pdev); struct at91_ide_info *info; if (!host) diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 8d43510..ba0d8a2 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1596,7 +1596,7 @@ static int bfin_atapi_probe(struct platform_device *pdev) return -ENODEV; } - dev_set_drvdata(&pdev->dev, host); + platform_set_drvdata(pdev, host); return 0; } @@ -1610,11 +1610,9 @@ static int bfin_atapi_probe(struct platform_device *pdev) */ static int bfin_atapi_remove(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - struct ata_host *host = dev_get_drvdata(dev); + struct ata_host *host = platform_get_drvdata(pdev); ata_host_detach(host); - dev_set_drvdata(&pdev->dev, NULL); peripheral_free_list(atapi_io_port); @@ -1624,7 +1622,7 @@ static int bfin_atapi_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int bfin_atapi_suspend(struct platform_device *pdev, pm_message_t state) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = platform_get_drvdata(pdev); if (host) return ata_host_suspend(host, state); else @@ -1633,7 +1631,7 @@ static int bfin_atapi_suspend(struct platform_device *pdev, pm_message_t state) static int bfin_atapi_resume(struct platform_device *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = platform_get_drvdata(pdev); int ret; if (host) { diff --git a/drivers/ata/pata_imx.c b/drivers/ata/pata_imx.c index aa3d166..4ec7c04 100644 --- a/drivers/ata/pata_imx.c +++ b/drivers/ata/pata_imx.c @@ -177,7 +177,7 @@ err: static int pata_imx_remove(struct platform_device *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = platform_get_drvdata(pdev); struct pata_imx_priv *priv = host->private_data; ata_host_detach(host); diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 3a8fb28..0024ced 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -825,7 +825,7 @@ mpc52xx_ata_remove(struct platform_device *op) static int mpc52xx_ata_suspend(struct platform_device *op, pm_message_t state) { - struct ata_host *host = dev_get_drvdata(&op->dev); + struct ata_host *host = platform_get_drvdata(op); return ata_host_suspend(host, state); } @@ -833,7 +833,7 @@ mpc52xx_ata_suspend(struct platform_device *op, pm_message_t state) static int mpc52xx_ata_resume(struct platform_device *op) { - struct ata_host *host = dev_get_drvdata(&op->dev); + struct ata_host *host = platform_get_drvdata(op); struct mpc52xx_ata_priv *priv = host->private_data; int rv; diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c index b0ac9e0..942ef94 100644 --- a/drivers/ata/pata_pxa.c +++ b/drivers/ata/pata_pxa.c @@ -371,7 +371,7 @@ static int pxa_ata_probe(struct platform_device *pdev) static int pxa_ata_remove(struct platform_device *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = platform_get_drvdata(pdev); struct pata_pxa_data *data = host->ports[0]->private_data; pxa_free_dma(data->dma_channel); diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index d40e403..19720a0 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1532,7 +1532,7 @@ static int sata_fsl_probe(struct platform_device *ofdev) ata_host_activate(host, irq, sata_fsl_interrupt, SATA_FSL_IRQ_FLAG, &sata_fsl_sht); - dev_set_drvdata(&ofdev->dev, host); + platform_set_drvdata(ofdev, host); host_priv->intr_coalescing.show = fsl_sata_intr_coalescing_show; host_priv->intr_coalescing.store = fsl_sata_intr_coalescing_store; @@ -1558,10 +1558,8 @@ static int sata_fsl_probe(struct platform_device *ofdev) error_exit_with_cleanup: - if (host) { - dev_set_drvdata(&ofdev->dev, NULL); + if (host) ata_host_detach(host); - } if (hcr_base) iounmap(hcr_base); @@ -1572,7 +1570,7 @@ error_exit_with_cleanup: static int sata_fsl_remove(struct platform_device *ofdev) { - struct ata_host *host = dev_get_drvdata(&ofdev->dev); + struct ata_host *host = platform_get_drvdata(ofdev); struct sata_fsl_host_priv *host_priv = host->private_data; device_remove_file(&ofdev->dev, &host_priv->intr_coalescing); @@ -1580,8 +1578,6 @@ static int sata_fsl_remove(struct platform_device *ofdev) ata_host_detach(host); - dev_set_drvdata(&ofdev->dev, NULL); - irq_dispose_mapping(host_priv->irq); iounmap(host_priv->hcr_base); kfree(host_priv); @@ -1592,13 +1588,13 @@ static int sata_fsl_remove(struct platform_device *ofdev) #ifdef CONFIG_PM static int sata_fsl_suspend(struct platform_device *op, pm_message_t state) { - struct ata_host *host = dev_get_drvdata(&op->dev); + struct ata_host *host = platform_get_drvdata(op); return ata_host_suspend(host, state); } static int sata_fsl_resume(struct platform_device *op) { - struct ata_host *host = dev_get_drvdata(&op->dev); + struct ata_host *host = platform_get_drvdata(op); struct sata_fsl_host_priv *host_priv = host->private_data; int ret; void __iomem *hcr_base = host_priv->hcr_base; diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 4799868..889c25a 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -825,7 +825,7 @@ cleanup: static int sata_rcar_remove(struct platform_device *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = platform_get_drvdata(pdev); struct sata_rcar_priv *priv = host->private_data; ata_host_detach(host); -- cgit v0.10.2 From 5c23341ff66c9280c2e76dc9795cd14497ea780f Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Fri, 24 May 2013 11:05:59 +0900 Subject: libata: do not limit R-Car SATA driver to shmobile The motivation for this is to allow the driver to be used with the r8a7790 SoC. I believe that rather than adding another SoC to the list of allowed SoCs it is better to simply remove the dependency of the driver on shmobile all together. Signed-off-by: Simon Horman Signed-off-by: Tejun Heo diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index a5a3ebc..aba6e93 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -263,7 +263,6 @@ config SATA_PROMISE config SATA_RCAR tristate "Renesas R-Car SATA support" - depends on ARCH_SHMOBILE && ARCH_R8A7779 help This option enables support for Renesas R-Car Serial ATA. -- cgit v0.10.2 From 333279c82b984f3eac61feff2b76a8b79e3db6c8 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 28 May 2013 02:43:23 +0400 Subject: sata_rcar: kill superfluous code in sata_rcar_bmdma_fill_sg() I've modified sata_rcar_bmdma_fill_sg() to take care of splitting long scatter/ gather segments due to the descriptor table transfer counter being only 28 bits wide (bit 1 to bit 28) but that was in vain as even if 'sata_rcar_sht' specified a correct 'dma_boundary' field, the DMA and block layers would have split the S/G segments on the necassary boundaries. Since the driver uses ATA_BMDMA_SHT() to initilaize 'sata_rcar_sht', the boundary is much smaller, only 0xFFFF, so the code I've added is even more useless, and it's better to just remove it. Signed-off-by: Sergei Shtylyov Signed-off-by: Tejun Heo diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 889c25a..629b07c 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -474,11 +474,10 @@ static void sata_rcar_bmdma_fill_sg(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct ata_bmdma_prd *prd = ap->bmdma_prd; struct scatterlist *sg; - unsigned int si, pi; + unsigned int si; - pi = 0; for_each_sg(qc->sg, sg, qc->n_elem, si) { - u32 addr, sg_len, len; + u32 addr, sg_len; /* * Note: h/w doesn't support 64-bit, so we unconditionally @@ -487,24 +486,13 @@ static void sata_rcar_bmdma_fill_sg(struct ata_queued_cmd *qc) addr = (u32)sg_dma_address(sg); sg_len = sg_dma_len(sg); - /* H/w transfer count is only 29 bits long, let's be careful */ - while (sg_len) { - len = sg_len; - if (len > 0x1ffffffe) - len = 0x1ffffffe; - - prd[pi].addr = cpu_to_le32(addr); - prd[pi].flags_len = cpu_to_le32(len); - VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len); - - pi++; - sg_len -= len; - addr += len; - } + prd[si].addr = cpu_to_le32(addr); + prd[si].flags_len = cpu_to_le32(sg_len); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", si, addr, sg_len); } /* end-of-table flag */ - prd[pi - 1].addr |= cpu_to_le32(SATA_RCAR_DTEND); + prd[si - 1].addr |= cpu_to_le32(SATA_RCAR_DTEND); } static void sata_rcar_qc_prep(struct ata_queued_cmd *qc) -- cgit v0.10.2 From 8bfbeed58665dbbf63813017712bd0c8e978379e Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 28 May 2013 02:45:08 +0400 Subject: sata_rcar: correct 'sata_rcar_sht' Using ATA_BMDMA_SHT() to intialize 'sata_rcar_sht' was suboptimal as the R-Car descriptor table transfer counter is 28 bits wide (bit 1 to bit 28), so that the 'dma_boundary' field of 0xFFFF is just too small, as well as the 'sg_tablesize' field of 128. Use ATA_BASE_SHT() to initialize 'sata_rcar_sht' instead and give proper values to the 'dma_boundary' and 'sg_tablesize' fields explicitly. Signed-off-by: Sergei Shtylyov Signed-off-by: Tejun Heo diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 629b07c..178165b 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -121,6 +121,8 @@ /* Descriptor table word 0 bit (when DTA32M = 1) */ #define SATA_RCAR_DTEND BIT(0) +#define SATA_RCAR_DMA_BOUNDARY 0x1FFFFFFEUL + struct sata_rcar_priv { void __iomem *base; struct clk *clk; @@ -575,7 +577,14 @@ static u8 sata_rcar_bmdma_status(struct ata_port *ap) } static struct scsi_host_template sata_rcar_sht = { - ATA_BMDMA_SHT(DRV_NAME), + ATA_BASE_SHT(DRV_NAME), + /* + * This controller allows transfer chunks up to 512MB which cross 64KB + * boundaries, therefore the DMA limits are more relaxed than standard + * ATA SFF. + */ + .sg_tablesize = ATA_MAX_PRD, + .dma_boundary = SATA_RCAR_DMA_BOUNDARY, }; static struct ata_port_operations sata_rcar_port_ops = { -- cgit v0.10.2 From 1b20f6a9adaa4b88d520d279c3d605f65b898625 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 28 May 2013 02:46:41 +0400 Subject: sata_rcar: add 'base' local variable to some functions The 'base' field of 'struct sata_rcar_priv' is used very often throughout the driver, so it seems worth loading it into a local variable if it's used more than once in a function. While at it, put some unitialized variables after intialized ones for aesthetic reasons. :-) Signed-off-by: Sergei Shtylyov Signed-off-by: Tejun Heo diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 178165b..f0d3e43 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -130,41 +130,44 @@ struct sata_rcar_priv { static void sata_rcar_phy_initialize(struct sata_rcar_priv *priv) { + void __iomem *base = priv->base; + /* idle state */ - iowrite32(0, priv->base + SATAPHYADDR_REG); + iowrite32(0, base + SATAPHYADDR_REG); /* reset */ - iowrite32(SATAPHYRESET_PHYRST, priv->base + SATAPHYRESET_REG); + iowrite32(SATAPHYRESET_PHYRST, base + SATAPHYRESET_REG); udelay(10); /* deassert reset */ - iowrite32(0, priv->base + SATAPHYRESET_REG); + iowrite32(0, base + SATAPHYRESET_REG); } static void sata_rcar_phy_write(struct sata_rcar_priv *priv, u16 reg, u32 val, int group) { + void __iomem *base = priv->base; int timeout; /* deassert reset */ - iowrite32(0, priv->base + SATAPHYRESET_REG); + iowrite32(0, base + SATAPHYRESET_REG); /* lane 1 */ - iowrite32(SATAPHYACCEN_PHYLANE, priv->base + SATAPHYACCEN_REG); + iowrite32(SATAPHYACCEN_PHYLANE, base + SATAPHYACCEN_REG); /* write phy register value */ - iowrite32(val, priv->base + SATAPHYWDATA_REG); + iowrite32(val, base + SATAPHYWDATA_REG); /* set register group */ if (group) reg |= SATAPHYADDR_PHYRATEMODE; /* write command */ - iowrite32(SATAPHYADDR_PHYCMD_WRITE | reg, priv->base + SATAPHYADDR_REG); + iowrite32(SATAPHYADDR_PHYCMD_WRITE | reg, base + SATAPHYADDR_REG); /* wait for ack */ for (timeout = 0; timeout < 100; timeout++) { - val = ioread32(priv->base + SATAPHYACK_REG); + val = ioread32(base + SATAPHYACK_REG); if (val & SATAPHYACK_PHYACK) break; } if (timeout >= 100) pr_err("%s timeout\n", __func__); /* idle state */ - iowrite32(0, priv->base + SATAPHYADDR_REG); + iowrite32(0, base + SATAPHYADDR_REG); } static void sata_rcar_freeze(struct ata_port *ap) @@ -180,14 +183,15 @@ static void sata_rcar_freeze(struct ata_port *ap) static void sata_rcar_thaw(struct ata_port *ap) { struct sata_rcar_priv *priv = ap->host->private_data; + void __iomem *base = priv->base; /* ack */ - iowrite32(~SATA_RCAR_INT_MASK, priv->base + SATAINTSTAT_REG); + iowrite32(~SATA_RCAR_INT_MASK, base + SATAINTSTAT_REG); ata_sff_thaw(ap); /* unmask */ - iowrite32(0x7ff & ~SATA_RCAR_INT_MASK, priv->base + SATAINTMASK_REG); + iowrite32(0x7ff & ~SATA_RCAR_INT_MASK, base + SATAINTMASK_REG); } static void sata_rcar_ioread16_rep(void __iomem *reg, void *buffer, int count) @@ -509,15 +513,16 @@ static void sata_rcar_bmdma_setup(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; unsigned int rw = qc->tf.flags & ATA_TFLAG_WRITE; - u32 dmactl; struct sata_rcar_priv *priv = ap->host->private_data; + void __iomem *base = priv->base; + u32 dmactl; /* load PRD table addr. */ mb(); /* make sure PRD table writes are visible to controller */ - iowrite32(ap->bmdma_prd_dma, priv->base + ATAPI_DTB_ADR_REG); + iowrite32(ap->bmdma_prd_dma, base + ATAPI_DTB_ADR_REG); /* specify data direction, triple-check start bit is clear */ - dmactl = ioread32(priv->base + ATAPI_CONTROL1_REG); + dmactl = ioread32(base + ATAPI_CONTROL1_REG); dmactl &= ~(ATAPI_CONTROL1_RW | ATAPI_CONTROL1_STOP); if (dmactl & ATAPI_CONTROL1_START) { dmactl &= ~ATAPI_CONTROL1_START; @@ -525,7 +530,7 @@ static void sata_rcar_bmdma_setup(struct ata_queued_cmd *qc) } if (!rw) dmactl |= ATAPI_CONTROL1_RW; - iowrite32(dmactl, priv->base + ATAPI_CONTROL1_REG); + iowrite32(dmactl, base + ATAPI_CONTROL1_REG); /* issue r/w command */ ap->ops->sff_exec_command(ap, &qc->tf); @@ -534,27 +539,29 @@ static void sata_rcar_bmdma_setup(struct ata_queued_cmd *qc) static void sata_rcar_bmdma_start(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - u32 dmactl; struct sata_rcar_priv *priv = ap->host->private_data; + void __iomem *base = priv->base; + u32 dmactl; /* start host DMA transaction */ - dmactl = ioread32(priv->base + ATAPI_CONTROL1_REG); + dmactl = ioread32(base + ATAPI_CONTROL1_REG); dmactl |= ATAPI_CONTROL1_START; - iowrite32(dmactl, priv->base + ATAPI_CONTROL1_REG); + iowrite32(dmactl, base + ATAPI_CONTROL1_REG); } static void sata_rcar_bmdma_stop(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct sata_rcar_priv *priv = ap->host->private_data; + void __iomem *base = priv->base; u32 dmactl; /* force termination of DMA transfer if active */ - dmactl = ioread32(priv->base + ATAPI_CONTROL1_REG); + dmactl = ioread32(base + ATAPI_CONTROL1_REG); if (dmactl & ATAPI_CONTROL1_START) { dmactl &= ~ATAPI_CONTROL1_START; dmactl |= ATAPI_CONTROL1_STOP; - iowrite32(dmactl, priv->base + ATAPI_CONTROL1_REG); + iowrite32(dmactl, base + ATAPI_CONTROL1_REG); } /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ @@ -564,8 +571,8 @@ static void sata_rcar_bmdma_stop(struct ata_queued_cmd *qc) static u8 sata_rcar_bmdma_status(struct ata_port *ap) { struct sata_rcar_priv *priv = ap->host->private_data; - u32 status; u8 host_stat = 0; + u32 status; status = ioread32(priv->base + ATAPI_STATUS_REG); if (status & ATAPI_STATUS_DEVINT) @@ -666,19 +673,19 @@ static irqreturn_t sata_rcar_interrupt(int irq, void *dev_instance) { struct ata_host *host = dev_instance; struct sata_rcar_priv *priv = host->private_data; - struct ata_port *ap; + void __iomem *base = priv->base; unsigned int handled = 0; + struct ata_port *ap; u32 sataintstat; unsigned long flags; spin_lock_irqsave(&host->lock, flags); - sataintstat = ioread32(priv->base + SATAINTSTAT_REG); + sataintstat = ioread32(base + SATAINTSTAT_REG); if (!sataintstat) goto done; /* ack */ - iowrite32(sataintstat & ~SATA_RCAR_INT_MASK, - priv->base + SATAINTSTAT_REG); + iowrite32(sataintstat & ~SATA_RCAR_INT_MASK, base + SATAINTSTAT_REG); ap = host->ports[0]; @@ -699,15 +706,16 @@ static void sata_rcar_setup_port(struct ata_host *host) struct ata_port *ap = host->ports[0]; struct ata_ioports *ioaddr = &ap->ioaddr; struct sata_rcar_priv *priv = host->private_data; + void __iomem *base = priv->base; ap->ops = &sata_rcar_port_ops; ap->pio_mask = ATA_PIO4; ap->udma_mask = ATA_UDMA6; ap->flags |= ATA_FLAG_SATA; - ioaddr->cmd_addr = priv->base + SDATA_REG; - ioaddr->ctl_addr = priv->base + SSDEVCON_REG; - ioaddr->scr_addr = priv->base + SCRSSTS_REG; + ioaddr->cmd_addr = base + SDATA_REG; + ioaddr->ctl_addr = base + SSDEVCON_REG; + ioaddr->scr_addr = base + SCRSSTS_REG; ioaddr->altstatus_addr = ioaddr->ctl_addr; ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << 2); @@ -725,6 +733,7 @@ static void sata_rcar_setup_port(struct ata_host *host) static void sata_rcar_init_controller(struct ata_host *host) { struct sata_rcar_priv *priv = host->private_data; + void __iomem *base = priv->base; u32 val; /* reset and setup phy */ @@ -737,27 +746,27 @@ static void sata_rcar_init_controller(struct ata_host *host) sata_rcar_phy_write(priv, SATAPCTLR4_REG, 0x28E80000, 0); /* SATA-IP reset state */ - val = ioread32(priv->base + ATAPI_CONTROL1_REG); + val = ioread32(base + ATAPI_CONTROL1_REG); val |= ATAPI_CONTROL1_RESET; - iowrite32(val, priv->base + ATAPI_CONTROL1_REG); + iowrite32(val, base + ATAPI_CONTROL1_REG); /* ISM mode, PRD mode, DTEND flag at bit 0 */ - val = ioread32(priv->base + ATAPI_CONTROL1_REG); + val = ioread32(base + ATAPI_CONTROL1_REG); val |= ATAPI_CONTROL1_ISM; val |= ATAPI_CONTROL1_DESE; val |= ATAPI_CONTROL1_DTA32M; - iowrite32(val, priv->base + ATAPI_CONTROL1_REG); + iowrite32(val, base + ATAPI_CONTROL1_REG); /* Release the SATA-IP from the reset state */ - val = ioread32(priv->base + ATAPI_CONTROL1_REG); + val = ioread32(base + ATAPI_CONTROL1_REG); val &= ~ATAPI_CONTROL1_RESET; - iowrite32(val, priv->base + ATAPI_CONTROL1_REG); + iowrite32(val, base + ATAPI_CONTROL1_REG); /* ack and mask */ - iowrite32(0, priv->base + SATAINTSTAT_REG); - iowrite32(0x7ff, priv->base + SATAINTMASK_REG); + iowrite32(0, base + SATAINTSTAT_REG); + iowrite32(0x7ff, base + SATAINTMASK_REG); /* enable interrupts */ - iowrite32(ATAPI_INT_ENABLE_SATAINT, priv->base + ATAPI_INT_ENABLE_REG); + iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG); } static int sata_rcar_probe(struct platform_device *pdev) @@ -824,14 +833,15 @@ static int sata_rcar_remove(struct platform_device *pdev) { struct ata_host *host = platform_get_drvdata(pdev); struct sata_rcar_priv *priv = host->private_data; + void __iomem *base = priv->base; ata_host_detach(host); /* disable interrupts */ - iowrite32(0, priv->base + ATAPI_INT_ENABLE_REG); + iowrite32(0, base + ATAPI_INT_ENABLE_REG); /* ack and mask */ - iowrite32(0, priv->base + SATAINTSTAT_REG); - iowrite32(0x7ff, priv->base + SATAINTMASK_REG); + iowrite32(0, base + SATAINTSTAT_REG); + iowrite32(0x7ff, base + SATAINTMASK_REG); clk_disable(priv->clk); @@ -843,14 +853,15 @@ static int sata_rcar_suspend(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); struct sata_rcar_priv *priv = host->private_data; + void __iomem *base = priv->base; int ret; ret = ata_host_suspend(host, PMSG_SUSPEND); if (!ret) { /* disable interrupts */ - iowrite32(0, priv->base + ATAPI_INT_ENABLE_REG); + iowrite32(0, base + ATAPI_INT_ENABLE_REG); /* mask */ - iowrite32(0x7ff, priv->base + SATAINTMASK_REG); + iowrite32(0x7ff, base + SATAINTMASK_REG); clk_disable(priv->clk); } @@ -862,14 +873,15 @@ static int sata_rcar_resume(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); struct sata_rcar_priv *priv = host->private_data; + void __iomem *base = priv->base; clk_enable(priv->clk); /* ack and mask */ - iowrite32(0, priv->base + SATAINTSTAT_REG); - iowrite32(0x7ff, priv->base + SATAINTMASK_REG); + iowrite32(0, base + SATAINTSTAT_REG); + iowrite32(0x7ff, base + SATAINTMASK_REG); /* enable interrupts */ - iowrite32(ATAPI_INT_ENABLE_SATAINT, priv->base + ATAPI_INT_ENABLE_REG); + iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG); ata_host_resume(host); -- cgit v0.10.2 From f6e984e63638e3bfb0f13f603a0e972a6da07deb Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 21 May 2013 23:24:22 +0400 Subject: ipr: qc_fill_rtf() method should not store alternate status register The 'ctl' field of the 'struct ata_taskfile' is not really dual purpose, i.e. it is not intended for storing the alternate status register (which is mapped at the same address in the legacy IDE controllers) in the qc_fill_rtf() method. No other 'libata' driver except 'drivers/scsi/ipr.c' stores the alternate status register's value in the 'ctl' field of 'qc->result_tf', hence this driver should not do this as well... Signed-off-by: Sergei Shtylyov Acked-by: Brian King Signed-off-by: Tejun Heo diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 82a3c1e..e6b05ec 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6662,7 +6662,6 @@ static bool ipr_qc_fill_rtf(struct ata_queued_cmd *qc) tf->hob_lbal = g->hob_lbal; tf->hob_lbam = g->hob_lbam; tf->hob_lbah = g->hob_lbah; - tf->ctl = g->alt_status; return true; } -- cgit v0.10.2 From 0a86e1c857134efe2cdb31d74bc7ea21721db494 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 3 Jun 2013 14:05:36 +0900 Subject: ata: use pci_get_drvdata() Use the wrapper function for getting the driver data using pci_dev instead of using dev_get_drvdata() with &pdev->dev, so we can directly pass a struct pci_dev. This is a purely cosmetic change. Signed-off-by: Jingoo Han Signed-off-by: Tejun Heo diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c index 4e94ba2..43365bb 100644 --- a/drivers/ata/acard-ahci.c +++ b/drivers/ata/acard-ahci.c @@ -128,7 +128,7 @@ static struct pci_driver acard_ahci_pci_driver = { #ifdef CONFIG_PM static int acard_ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); struct ahci_host_priv *hpriv = host->private_data; void __iomem *mmio = hpriv->mmio; u32 ctl; @@ -156,7 +156,7 @@ static int acard_ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg static int acard_ahci_pci_device_resume(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 4d1c672..da45325 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -616,7 +616,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, #ifdef CONFIG_PM static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); struct ahci_host_priv *hpriv = host->private_data; void __iomem *mmio = hpriv->mmio; u32 ctl; @@ -644,7 +644,7 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) static int ahci_pci_device_resume(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 2f48123..cab2d3a 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -988,7 +988,7 @@ static int piix_broken_suspend(void) static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); unsigned long flags; int rc = 0; @@ -1023,7 +1023,7 @@ static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) static int piix_pci_device_resume(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); unsigned long flags; int rc; @@ -1736,7 +1736,7 @@ static int piix_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) static void piix_remove_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); struct piix_host_priv *hpriv = host->private_data; pci_write_config_dword(pdev, PIIX_IOCFG, hpriv->saved_iocfg); diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 61da069..1b7b2cc 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -592,7 +592,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) #ifdef CONFIG_PM static int ali_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 82a0892..d23e2b3 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -578,7 +578,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) #ifdef CONFIG_PM static int amd_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 74b215c..1581dee 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -426,7 +426,7 @@ static const struct pci_device_id artop_pci_tbl[] = { #ifdef CONFIG_PM static int atp8xx_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c index 041f50d..2ca5026 100644 --- a/drivers/ata/pata_atp867x.c +++ b/drivers/ata/pata_atp867x.c @@ -534,7 +534,7 @@ err_out: #ifdef CONFIG_PM static int atp867x_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c index 504b98b..8fb69e5 100644 --- a/drivers/ata/pata_cmd640.c +++ b/drivers/ata/pata_cmd640.c @@ -235,7 +235,7 @@ static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id) #ifdef CONFIG_PM static int cmd640_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 2949cfc..1275a8d 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -491,7 +491,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) #ifdef CONFIG_PM static int cmd64x_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index bfcf377..f10baab 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -241,7 +241,7 @@ static int cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id) static int cs5520_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); u8 pcicfg; int rc; @@ -269,7 +269,7 @@ static int cs5520_reinit_one(struct pci_dev *pdev) static int cs5520_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc = 0; rc = ata_host_suspend(host, mesg); diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index 48389ae..f07f229 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c @@ -330,7 +330,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) #ifdef CONFIG_PM static int cs5530_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 4be884a..35b5213 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -390,7 +390,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) #ifdef CONFIG_PM static int hpt36x_reinit_one(struct pci_dev *dev) { - struct ata_host *host = dev_get_drvdata(&dev->dev); + struct ata_host *host = pci_get_drvdata(dev); int rc; rc = ata_pci_device_do_resume(dev); diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index 76c9314..85cf286 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c @@ -253,7 +253,7 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id) #ifdef CONFIG_PM static int hpt3x3_reinit_one(struct pci_dev *dev) { - struct ata_host *host = dev_get_drvdata(&dev->dev); + struct ata_host *host = pci_get_drvdata(dev); int rc; rc = ata_pci_device_do_resume(dev); diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 9cc05d8..581e04d 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -939,7 +939,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) #ifdef CONFIG_PM static int it821x_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index e5725ed..c28d064 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -1311,7 +1311,7 @@ static int pata_macio_pci_attach(struct pci_dev *pdev, static void pata_macio_pci_detach(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); ata_host_detach(host); } @@ -1320,14 +1320,14 @@ static void pata_macio_pci_detach(struct pci_dev *pdev) static int pata_macio_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); return pata_macio_do_suspend(host->private_data, mesg); } static int pata_macio_pci_resume(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); return pata_macio_do_resume(host->private_data); } diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index 12010ed..9513e07 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c @@ -157,7 +157,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id) static int ninja32_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index 6f6fa10..16dc3a6 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c @@ -389,7 +389,7 @@ static const struct pci_device_id ns87415_pci_tbl[] = { #ifdef CONFIG_PM static int ns87415_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index c76e659..9d874c8 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -765,7 +765,7 @@ static int pdc2027x_init_one(struct pci_dev *pdev, #ifdef CONFIG_PM static int pdc2027x_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); unsigned int board_idx; int rc; diff --git a/drivers/ata/pata_rdc.c b/drivers/ata/pata_rdc.c index 6a86655..79a970f 100644 --- a/drivers/ata/pata_rdc.c +++ b/drivers/ata/pata_rdc.c @@ -364,7 +364,7 @@ static int rdc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) static void rdc_remove_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); struct rdc_host_priv *hpriv = host->private_data; pci_write_config_dword(pdev, 0x54, hpriv->saved_iocfg); diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index 60f4de2..040b093 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -105,7 +105,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en #ifdef CONFIG_PM static int rz1000_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index f3febbc..96c6a79 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -440,7 +440,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id #ifdef CONFIG_PM static int serverworks_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 64c5f0d..c4b0b07 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -407,7 +407,7 @@ use_ioports: #ifdef CONFIG_PM static int sil680_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int try_mmio, rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 2d5ac13..1e83636 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -873,7 +873,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef CONFIG_PM static int sis_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 738e000..6816911 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c @@ -341,7 +341,7 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id #ifdef CONFIG_PM static int sl82c105_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index c8e589d..94473da 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c @@ -211,7 +211,7 @@ static const struct pci_device_id triflex[] = { #ifdef CONFIG_PM static int triflex_ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc = 0; rc = ata_host_suspend(host, mesg); diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 8d2a9fd..c3ab9a6 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -673,7 +673,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) static int via_reinit_one(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 1e6827c..e451317 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -776,7 +776,7 @@ static int init_controller(void __iomem *mmio_base, u16 hctl) #ifdef CONFIG_PM static int inic_pci_device_resume(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); struct inic_host_priv *hpriv = host->private_data; int rc; diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 85ee499..d74def8 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -2435,7 +2435,7 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef CONFIG_PM static int nv_pci_device_resume(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); struct nv_host_priv *hpriv = host->private_data; int rc; diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index a7b3167..a6da219 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -805,7 +805,7 @@ static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef CONFIG_PM static int sil_pci_device_resume(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); int rc; rc = ata_pci_device_do_resume(pdev); diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 59f0d63..aa1051b 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -1353,7 +1353,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef CONFIG_PM static int sil24_pci_device_resume(struct pci_dev *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = pci_get_drvdata(pdev); void __iomem *host_base = host->iomap[SIL24_HOST_BAR]; int rc; -- cgit v0.10.2 From ddfef5de3d716f77bad32dbbba6b280158dfd721 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Mon, 3 Jun 2013 08:22:54 -0500 Subject: sata_highbank: increase retry count but shorten duration for Calxeda controller Increase the retry count for the hard reset function to 100 but shorten the time out period to 500 ms. See the comment for ahci_highbank_hardreset for the reasons why those vaulues were chosen. Signed-off-by: Mark Langsdorf Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index b20aa96..c846fd3 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -196,10 +196,26 @@ static int highbank_initialize_phys(struct device *dev, void __iomem *addr) return 0; } +/* + * The Calxeda SATA phy intermittently fails to bring up a link with Gen3 + * Retrying the phy hard reset can work around the issue, but the drive + * may fail again. In less than 150 out of 15000 test runs, it took more + * than 10 tries for the link to be established (but never more than 35). + * Triple the maximum observed retry count to provide plenty of margin for + * rare events and to guarantee that the link is established. + * + * Also, the default 2 second time-out on a failed drive is too long in + * this situation. The uboot implementation of the same driver function + * uses a much shorter time-out period and never experiences a time out + * issue. Reducing the time-out to 500ms improves the responsiveness. + * The other timing constants were kept the same as the stock AHCI driver. + * This change was also tested 15000 times on 24 drives and none of them + * experienced a time out. + */ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline) { - const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); + static const unsigned long timing[] = { 5, 100, 500}; struct ata_port *ap = link->ap; struct ahci_port_priv *pp = ap->private_data; u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; @@ -207,7 +223,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class, bool online; u32 sstatus; int rc; - int retry = 10; + int retry = 100; ahci_stop_engine(ap); -- cgit v0.10.2 From 5ba59b59cb413b9d89f40532bad3529d5185dd3c Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 3 Jun 2013 13:16:05 -0700 Subject: sata_rcar: fix compilation warning in sata_rcar_thaw() When compiling the driver with gcc 4.8, it gives the following warning: drivers/ata/sata_rcar.c: In function `sata_rcar_thaw': drivers/ata/sata_rcar.c:183:2: warning: large integer implicitly truncated to unsigned type [-Woverflow] Fix the warning by explicit cast of the 'unsigned long' value to 'u32'. Signed-off-by: Sergei Shtylyov Signed-off-by: Tejun Heo diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 249c8a2..d514234 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -180,7 +180,7 @@ static void sata_rcar_thaw(struct ata_port *ap) struct sata_rcar_priv *priv = ap->host->private_data; /* ack */ - iowrite32(~SATA_RCAR_INT_MASK, priv->base + SATAINTSTAT_REG); + iowrite32(~(u32)SATA_RCAR_INT_MASK, priv->base + SATAINTSTAT_REG); ata_sff_thaw(ap); -- cgit v0.10.2 From 439d7a358f93a52458527329939be9f97db1242a Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Thu, 30 May 2013 15:17:30 -0500 Subject: ahci: make ahci_transmit_led_message into a function pointer Create a new ata_port_operations function pointer called transmit_led_message and give it the default value of ahci_transmit_led_message. This allows AHCI controllers with non-standard LED interfaces to use the existing em_ interface. Signed-off-by: Mark Langsdorf Signed-off-by: Tejun Heo diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 3797a7b..64c3f1f 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -173,6 +173,7 @@ struct ata_port_operations ahci_ops = { .em_store = ahci_led_store, .sw_activity_show = ahci_activity_show, .sw_activity_store = ahci_activity_store, + .transmit_led_message = ahci_transmit_led_message, #ifdef CONFIG_PM .port_suspend = ahci_port_suspend, .port_resume = ahci_port_resume, @@ -774,7 +775,7 @@ static void ahci_start_port(struct ata_port *ap) /* EM Transmit bit maybe busy during init */ for (i = 0; i < EM_MAX_RETRY; i++) { - rc = ahci_transmit_led_message(ap, + rc = ap->ops->transmit_led_message(ap, emp->led_state, 4); if (rc == -EBUSY) @@ -915,7 +916,7 @@ static void ahci_sw_activity_blink(unsigned long arg) led_message |= (1 << 16); } spin_unlock_irqrestore(ap->lock, flags); - ahci_transmit_led_message(ap, led_message, 4); + ap->ops->transmit_led_message(ap, led_message, 4); } static void ahci_init_sw_activity(struct ata_link *link) @@ -1044,7 +1045,7 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, if (emp->blink_policy) state &= ~EM_MSG_LED_VALUE_ACTIVITY; - return ahci_transmit_led_message(ap, state, size); + return ap->ops->transmit_led_message(ap, state, size); } static ssize_t ahci_activity_store(struct ata_device *dev, enum sw_activity val) @@ -1063,7 +1064,7 @@ static ssize_t ahci_activity_store(struct ata_device *dev, enum sw_activity val) /* set the LED to OFF */ port_led_state &= EM_MSG_LED_VALUE_OFF; port_led_state |= (ap->port_no | (link->pmp << 8)); - ahci_transmit_led_message(ap, port_led_state, 4); + ap->ops->transmit_led_message(ap, port_led_state, 4); } else { link->flags |= ATA_LFLAG_SW_ACTIVITY; if (val == BLINK_OFF) { @@ -1071,7 +1072,7 @@ static ssize_t ahci_activity_store(struct ata_device *dev, enum sw_activity val) port_led_state &= EM_MSG_LED_VALUE_OFF; port_led_state |= (ap->port_no | (link->pmp << 8)); port_led_state |= EM_MSG_LED_VALUE_ON; /* check this */ - ahci_transmit_led_message(ap, port_led_state, 4); + ap->ops->transmit_led_message(ap, port_led_state, 4); } } emp->blink_policy = val; diff --git a/include/linux/libata.h b/include/linux/libata.h index c886dc87..4ea55bb 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -910,6 +910,9 @@ struct ata_port_operations { ssize_t (*sw_activity_show)(struct ata_device *dev, char *buf); ssize_t (*sw_activity_store)(struct ata_device *dev, enum sw_activity val); + ssize_t (*transmit_led_message)(struct ata_port *ap, u32 state, + ssize_t size); + /* * Obsolete */ -- cgit v0.10.2 From d50b110f14ad07066f9ad6e7f32e2b1a595b92f9 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Thu, 6 Jun 2013 07:52:41 -0500 Subject: sata highbank: add bit-banged SGPIO driver support Highbank supports SGPIO by bit-banging out the SGPIO signals over three GPIO pins defined in the DTB. Add support for this SGPIO functionality. Signed-off-by: Mark Langsdorf Signed-off-by: Tejun Heo diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index b519f9b..3ec0c5c 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt @@ -12,6 +12,11 @@ Optional properties: - calxeda,port-phys: phandle-combophy and lane assignment, which maps each SATA port to a combophy and a lane within that combophy +- calxeda,sgpio-gpio: phandle-gpio bank, bit offset, and default on or off, + which indicates that the driver supports SGPIO + indicator lights using the indicated GPIOs +- calxeda,led-order : a u32 array that map port numbers to offsets within the + SGPIO bitstream. - dma-coherent : Present if dma operations are coherent Example: diff --git a/arch/arm/boot/dts/ecx-common.dtsi b/arch/arm/boot/dts/ecx-common.dtsi index d61b535..e8559b7 100644 --- a/arch/arm/boot/dts/ecx-common.dtsi +++ b/arch/arm/boot/dts/ecx-common.dtsi @@ -33,6 +33,8 @@ calxeda,port-phys = <&combophy5 0 &combophy0 0 &combophy0 1 &combophy0 2 &combophy0 3>; + calxeda,sgpio-gpio =<&gpioh 5 1 &gpioh 6 1 &gpioh 7 1>; + calxeda,led-order = <4 0 1 2 3>; }; sdhci@ffe0e000 { diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 05adf29..adfb2df 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -322,6 +322,7 @@ struct ahci_host_priv { u32 em_buf_sz; /* EM buffer size in byte */ u32 em_msg_type; /* EM message type */ struct clk *clk; /* Only for platforms supporting clk */ + void *plat_data; /* Other platform data */ }; extern int ahci_ignore_sss; diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index b20aa96..8de8ac8 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -33,6 +33,9 @@ #include #include #include +#include +#include + #include "ahci.h" #define CPHY_MAP(dev, addr) ((((dev) & 0x1f) << 7) | (((addr) >> 9) & 0x7f)) @@ -66,6 +69,146 @@ struct phy_lane_info { }; static struct phy_lane_info port_data[CPHY_PORT_COUNT]; +static DEFINE_SPINLOCK(sgpio_lock); +#define SCLOCK 0 +#define SLOAD 1 +#define SDATA 2 +#define SGPIO_PINS 3 +#define SGPIO_PORTS 8 + +/* can be cast as an ahci_host_priv for compatibility with most functions */ +struct ecx_plat_data { + u32 n_ports; + unsigned sgpio_gpio[SGPIO_PINS]; + u32 sgpio_pattern; + u32 port_to_sgpio[SGPIO_PORTS]; +}; + +#define SGPIO_SIGNALS 3 +#define ECX_ACTIVITY_BITS 0x300000 +#define ECX_ACTIVITY_SHIFT 2 +#define ECX_LOCATE_BITS 0x80000 +#define ECX_LOCATE_SHIFT 1 +#define ECX_FAULT_BITS 0x400000 +#define ECX_FAULT_SHIFT 0 +static inline int sgpio_bit_shift(struct ecx_plat_data *pdata, u32 port, + u32 shift) +{ + return 1 << (3 * pdata->port_to_sgpio[port] + shift); +} + +static void ecx_parse_sgpio(struct ecx_plat_data *pdata, u32 port, u32 state) +{ + if (state & ECX_ACTIVITY_BITS) + pdata->sgpio_pattern |= sgpio_bit_shift(pdata, port, + ECX_ACTIVITY_SHIFT); + else + pdata->sgpio_pattern &= ~sgpio_bit_shift(pdata, port, + ECX_ACTIVITY_SHIFT); + if (state & ECX_LOCATE_BITS) + pdata->sgpio_pattern |= sgpio_bit_shift(pdata, port, + ECX_LOCATE_SHIFT); + else + pdata->sgpio_pattern &= ~sgpio_bit_shift(pdata, port, + ECX_LOCATE_SHIFT); + if (state & ECX_FAULT_BITS) + pdata->sgpio_pattern |= sgpio_bit_shift(pdata, port, + ECX_FAULT_SHIFT); + else + pdata->sgpio_pattern &= ~sgpio_bit_shift(pdata, port, + ECX_FAULT_SHIFT); +} + +/* + * Tell the LED controller that the signal has changed by raising the clock + * line for 50 uS and then lowering it for 50 uS. + */ +static void ecx_led_cycle_clock(struct ecx_plat_data *pdata) +{ + gpio_set_value(pdata->sgpio_gpio[SCLOCK], 1); + udelay(50); + gpio_set_value(pdata->sgpio_gpio[SCLOCK], 0); + udelay(50); +} + +static ssize_t ecx_transmit_led_message(struct ata_port *ap, u32 state, + ssize_t size) +{ + struct ahci_host_priv *hpriv = ap->host->private_data; + struct ecx_plat_data *pdata = (struct ecx_plat_data *) hpriv->plat_data; + struct ahci_port_priv *pp = ap->private_data; + unsigned long flags; + int pmp, i; + struct ahci_em_priv *emp; + u32 sgpio_out; + + /* get the slot number from the message */ + pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; + if (pmp < EM_MAX_SLOTS) + emp = &pp->em_priv[pmp]; + else + return -EINVAL; + + if (!(hpriv->em_msg_type & EM_MSG_TYPE_LED)) + return size; + + spin_lock_irqsave(&sgpio_lock, flags); + ecx_parse_sgpio(pdata, ap->port_no, state); + sgpio_out = pdata->sgpio_pattern; + gpio_set_value(pdata->sgpio_gpio[SLOAD], 1); + ecx_led_cycle_clock(pdata); + gpio_set_value(pdata->sgpio_gpio[SLOAD], 0); + /* + * bit-bang out the SGPIO pattern, by consuming a bit and then + * clocking it out. + */ + for (i = 0; i < (SGPIO_SIGNALS * pdata->n_ports); i++) { + gpio_set_value(pdata->sgpio_gpio[SDATA], sgpio_out & 1); + sgpio_out >>= 1; + ecx_led_cycle_clock(pdata); + } + + /* save off new led state for port/slot */ + emp->led_state = state; + + spin_unlock_irqrestore(&sgpio_lock, flags); + return size; +} + +static void highbank_set_em_messages(struct device *dev, + struct ahci_host_priv *hpriv, + struct ata_port_info *pi) +{ + struct device_node *np = dev->of_node; + struct ecx_plat_data *pdata = hpriv->plat_data; + int i; + int err; + + for (i = 0; i < SGPIO_PINS; i++) { + err = of_get_named_gpio(np, "calxeda,sgpio-gpio", i); + if (IS_ERR_VALUE(err)) + return; + + pdata->sgpio_gpio[i] = err; + err = gpio_request(pdata->sgpio_gpio[i], "CX SGPIO"); + if (err) { + pr_err("sata_highbank gpio_request %d failed: %d\n", + i, err); + return; + } + gpio_direction_output(pdata->sgpio_gpio[i], 1); + } + of_property_read_u32_array(np, "calxeda,led-order", + pdata->port_to_sgpio, + pdata->n_ports); + + /* store em_loc */ + hpriv->em_loc = 0; + hpriv->em_buf_sz = 4; + hpriv->em_msg_type = EM_MSG_TYPE_LED; + pi->flags |= ATA_FLAG_EM | ATA_FLAG_SW_ACTIVITY; +} + static u32 __combo_phy_reg_read(u8 sata_port, u32 addr) { u32 data; @@ -241,6 +384,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class, static struct ata_port_operations ahci_highbank_ops = { .inherits = &ahci_ops, .hardreset = ahci_highbank_hardreset, + .transmit_led_message = ecx_transmit_led_message, }; static const struct ata_port_info ahci_highbank_port_info = { @@ -264,12 +408,13 @@ static int ahci_highbank_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ahci_host_priv *hpriv; + struct ecx_plat_data *pdata; struct ata_host *host; struct resource *mem; int irq; - int n_ports; int i; int rc; + u32 n_ports; struct ata_port_info pi = ahci_highbank_port_info; const struct ata_port_info *ppi[] = { &pi, NULL }; @@ -290,6 +435,11 @@ static int ahci_highbank_probe(struct platform_device *pdev) dev_err(dev, "can't alloc ahci_host_priv\n"); return -ENOMEM; } + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dev_err(dev, "can't alloc ecx_plat_data\n"); + return -ENOMEM; + } hpriv->flags |= (unsigned long)pi.private_data; @@ -313,8 +463,6 @@ static int ahci_highbank_probe(struct platform_device *pdev) if (hpriv->cap & HOST_CAP_PMP) pi.flags |= ATA_FLAG_PMP; - ahci_set_em_messages(hpriv, &pi); - /* CAP.NP sometimes indicate the index of the last enabled * port, at other times, that of the last possible port, so * determining the maximum port number requires looking at @@ -322,6 +470,10 @@ static int ahci_highbank_probe(struct platform_device *pdev) */ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); + pdata->n_ports = n_ports; + hpriv->plat_data = pdata; + highbank_set_em_messages(dev, hpriv, &pi); + host = ata_host_alloc_pinfo(dev, ppi, n_ports); if (!host) { rc = -ENOMEM; @@ -333,9 +485,6 @@ static int ahci_highbank_probe(struct platform_device *pdev) if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) host->flags |= ATA_HOST_PARALLEL_SCAN; - if (pi.flags & ATA_FLAG_EM) - ahci_reset_em(host); - for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; -- cgit v0.10.2 From 912b9ac683b112615d5605686f1dc086402ce9f7 Mon Sep 17 00:00:00 2001 From: Shane Huang Date: Sat, 8 Jun 2013 16:00:16 +0800 Subject: ahci: remove pmp link online check in FBS EH ata_link_online() check in ahci_error_intr() is unnecessary, it should be removed otherwise may lead to lockup with FBS enabled PMP. http://marc.info/?l=linux-ide&m=137050421603272&w=2 Reported-by: Yu Liu Signed-off-by: Shane Huang Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index a70ff15..7b9bdd8 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1560,8 +1560,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) u32 fbs = readl(port_mmio + PORT_FBS); int pmp = fbs >> PORT_FBS_DWE_OFFSET; - if ((fbs & PORT_FBS_SDE) && (pmp < ap->nr_pmp_links) && - ata_link_online(&ap->pmp_link[pmp])) { + if ((fbs & PORT_FBS_SDE) && (pmp < ap->nr_pmp_links)) { link = &ap->pmp_link[pmp]; fbs_need_dec = true; } -- cgit v0.10.2 From 7a87718d92760fc688628ad6a430643dafa16f1f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 11 Jun 2013 00:11:36 -0700 Subject: libata: skip SRST for all SIMG [34]7x port-multipliers For some reason, a lot of port-multipliers have issues with softreset. SIMG [34]7x series port-multipliers have been quite erratic in this regard. I recall that it was better with some firmware revisions and the current list of quirks worked fine for a while. I think it got worse with later firmwares or maybe my test coverage wasn't good enough. Anyways, HPA is reporting that his 3726 setup suffers SRST failures and then the PMP gets confused and fails to probe the last port. The hope was that we try to stick to the standard as much as possible and soonish the PMPs and their firmwares will improve in quality, so the quirk list was kept to minimum. Well, it seems like that's never gonna happen. Let's set NO_SRST for all [34]7x PMPs so that whatever remaining userbase of the device suffer the least. Maybe we should do the same for 57xx's but unfortunately I don't have any device left to test and I'm not even sure 57xx's have ever been made widely available, so let's leave those alone for now. Signed-off-by: Tejun Heo Reported-by: "H. Peter Anvin" Cc: stable@vger.kernel.org diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 61c59ee..1c41722 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -389,9 +389,13 @@ static void sata_pmp_quirks(struct ata_port *ap) /* link reports offline after LPM */ link->flags |= ATA_LFLAG_NO_LPM; - /* Class code report is unreliable. */ + /* + * Class code report is unreliable and SRST times + * out under certain configurations. + */ if (link->pmp < 5) - link->flags |= ATA_LFLAG_ASSUME_ATA; + link->flags |= ATA_LFLAG_NO_SRST | + ATA_LFLAG_ASSUME_ATA; /* port 5 is for SEMB device and it doesn't like SRST */ if (link->pmp == 5) @@ -399,20 +403,17 @@ static void sata_pmp_quirks(struct ata_port *ap) ATA_LFLAG_ASSUME_SEMB; } } else if (vendor == 0x1095 && devid == 0x4723) { - /* sil4723 quirks */ - ata_for_each_link(link, ap, EDGE) { - /* link reports offline after LPM */ - link->flags |= ATA_LFLAG_NO_LPM; - - /* class code report is unreliable */ - if (link->pmp < 2) - link->flags |= ATA_LFLAG_ASSUME_ATA; - - /* the config device at port 2 locks up on SRST */ - if (link->pmp == 2) - link->flags |= ATA_LFLAG_NO_SRST | - ATA_LFLAG_ASSUME_ATA; - } + /* + * sil4723 quirks + * + * Link reports offline after LPM. Class code report is + * unreliable. SIMG PMPs never got SRST reliable and the + * config device at port 2 locks up on SRST. + */ + ata_for_each_link(link, ap, EDGE) + link->flags |= ATA_LFLAG_NO_LPM | + ATA_LFLAG_NO_SRST | + ATA_LFLAG_ASSUME_ATA; } else if (vendor == 0x1095 && devid == 0x4726) { /* sil4726 quirks */ ata_for_each_link(link, ap, EDGE) { -- cgit v0.10.2 From 1e8f5f761ca3636bb6e281d9dd8adfa887b38eea Mon Sep 17 00:00:00 2001 From: Girish K S Date: Tue, 16 Apr 2013 14:58:02 +0530 Subject: ahci: sata: add support for exynos5440 sata This patch adds the compatible string of the exynos5440 sata controller compliant with the ahci 1.3 and sata 3.0 specification. changes in v2: changed the compatible string by adding the actual IP owners name instead of the SoC vendor name. Signed-off-by: Girish K S Signed-off-by: Tejun Heo diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 7a8a284..2daaee0 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -327,6 +327,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume); static const struct of_device_id ahci_of_match[] = { { .compatible = "snps,spear-ahci", }, + { .compatible = "snps,exynos5440-ahci", }, {}, }; MODULE_DEVICE_TABLE(of, ahci_of_match); -- cgit v0.10.2 From 78062c50d15d6a0adfa09f6e35a6c52abcc9a32d Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Tue, 18 Jun 2013 10:54:48 -0700 Subject: libata: cleanup SAT error translation - Remove duplicate Medium Error Entry. - Fix translations to match SAT2 translation table. - Remove warning messages when translation is not found when decoding error or status register. - Goes through status register decoding when only ABRT bit is set in error register. Tested: When a disk fails, it sets Status = 0x71 [DRDY DF ERR] , Error = 0x4 [ABRT] This patch will make the sense key HARDWARE_ERROR instead. When there is a simple command syntax error: Status = 0x51 [DRDY ERR] , Error = 0x4 [ABRT] The sense key remains ABORTED_COMMAND. tj: Some updates to the description and comments. Signed-off-by: Gwendal Grignou Signed-off-by: Tejun Heo diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index dd310b27..006f1bf 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -849,25 +849,24 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, /* Bad address mark */ {0x01, MEDIUM_ERROR, 0x13, 0x00}, // Address mark not found Address mark not found for data field /* TRK0 */ - {0x02, HARDWARE_ERROR, 0x00, 0x00}, // Track 0 not found Hardware error - /* Abort & !ICRC */ - {0x04, ABORTED_COMMAND, 0x00, 0x00}, // Aborted command Aborted command + {0x02, HARDWARE_ERROR, 0x00, 0x00}, // Track 0 not found Hardware error + /* Abort: 0x04 is not translated here, see below */ /* Media change request */ {0x08, NOT_READY, 0x04, 0x00}, // Media change request FIXME: faking offline - /* SRV */ - {0x10, ABORTED_COMMAND, 0x14, 0x00}, // ID not found Recorded entity not found - /* Media change */ - {0x08, NOT_READY, 0x04, 0x00}, // Media change FIXME: faking offline + /* SRV/IDNF */ + {0x10, ILLEGAL_REQUEST, 0x21, 0x00}, // ID not found Logical address out of range + /* MC */ + {0x20, UNIT_ATTENTION, 0x28, 0x00}, // Media Changed Not ready to ready change, medium may have changed /* ECC */ {0x40, MEDIUM_ERROR, 0x11, 0x04}, // Uncorrectable ECC error Unrecovered read error /* BBD - block marked bad */ - {0x80, MEDIUM_ERROR, 0x11, 0x04}, // Block marked bad Medium error, unrecovered read error + {0x80, MEDIUM_ERROR, 0x11, 0x04}, // Block marked bad Medium error, unrecovered read error {0xFF, 0xFF, 0xFF, 0xFF}, // END mark }; static const unsigned char stat_table[][4] = { /* Must be first because BUSY means no other bits valid */ {0x80, ABORTED_COMMAND, 0x47, 0x00}, // Busy, fake parity for now - {0x20, HARDWARE_ERROR, 0x00, 0x00}, // Device fault + {0x20, HARDWARE_ERROR, 0x44, 0x00}, // Device fault, internal target failure {0x08, ABORTED_COMMAND, 0x47, 0x00}, // Timed out in xfer, fake parity for now {0x04, RECOVERED_ERROR, 0x11, 0x00}, // Recovered ECC error Medium error, recovered {0xFF, 0xFF, 0xFF, 0xFF}, // END mark @@ -892,13 +891,13 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, goto translate_done; } } - /* No immediate match */ - if (verbose) - printk(KERN_WARNING "ata%u: no sense translation for " - "error 0x%02x\n", id, drv_err); } - /* Fall back to interpreting status bits */ + /* + * Fall back to interpreting status bits. Note that if the drv_err + * has only the ABRT bit set, we decode drv_stat. ABRT by itself + * is not descriptive enough. + */ for (i = 0; stat_table[i][0] != 0xFF; i++) { if (stat_table[i][0] & drv_stat) { *sk = stat_table[i][1]; @@ -907,13 +906,11 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, goto translate_done; } } - /* No error? Undecoded? */ - if (verbose) - printk(KERN_WARNING "ata%u: no sense translation for " - "status: 0x%02x\n", id, drv_stat); - /* We need a sensible error return here, which is tricky, and one - that won't cause people to do things like return a disk wrongly */ + /* + * We need a sensible error return here, which is tricky, and one + * that won't cause people to do things like return a disk wrongly. + */ *sk = ABORTED_COMMAND; *asc = 0x00; *ascq = 0x00; -- cgit v0.10.2 From c7e8695bfa0611b39493a9dfe8bab9f63f9809bd Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Wed, 19 Jun 2013 16:25:37 -0700 Subject: ata_piix: IDE-mode SATA patch for Intel Coleto Creek DeviceIDs This patch adds the IDE-mode SATA DeviceIDs for the Intel Coleto Creek PCH. Signed-off-by: Seth Heasley Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 9a8a674..8eae659 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -338,6 +338,8 @@ static const struct pci_device_id piix_pci_tbl[] = { /* SATA Controller IDE (BayTrail) */ { 0x8086, 0x0F20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt }, { 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt }, + /* SATA Controller IDE (Coleto Creek) */ + { 0x8086, 0x23a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { } /* terminate list */ }; -- cgit v0.10.2 From 1cfc7df3de10c40ed459e13cce6de616023bf41c Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Wed, 19 Jun 2013 16:36:45 -0700 Subject: ahci: AHCI-mode SATA patch for Intel Coleto Creek DeviceIDs This patch adds the AHCI-mode SATA DeviceIDs for the Intel Coleto Creek PCH. Signed-off-by: Seth Heasley Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 2b50dfd..e381f36 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -291,6 +291,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x8d64), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */ + { PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, -- cgit v0.10.2 From d0887c43f51c308b01605346e55d906ba858a6f9 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 23 Jun 2013 23:25:04 +0400 Subject: libata-zpodd: must use ata_tf_init() There are some SATA controllers which have both devices 0 and 1 but this module just zeroes out taskfile and sets then ATA_TFLAG_DEVICE (not sure that's needed) which could lead to a wrong device being selected just before issuing command. Thus we should call ata_tf_init() which sets up the device register value properly, like all other users of ata_exec_internal() do... Signed-off-by: Sergei Shtylyov Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c index 90b159b..cd8daf4 100644 --- a/drivers/ata/libata-zpodd.c +++ b/drivers/ata/libata-zpodd.c @@ -32,13 +32,14 @@ struct zpodd { static int eject_tray(struct ata_device *dev) { - struct ata_taskfile tf = {}; + struct ata_taskfile tf; const char cdb[] = { GPCMD_START_STOP_UNIT, 0, 0, 0, 0x02, /* LoEj */ 0, 0, 0, 0, 0, 0, 0, }; + ata_tf_init(dev, &tf); tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf.command = ATA_CMD_PACKET; tf.protocol = ATAPI_PROT_NODATA; @@ -52,8 +53,7 @@ static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev) char buf[16]; unsigned int ret; struct rm_feature_desc *desc = (void *)(buf + 8); - struct ata_taskfile tf = {}; - + struct ata_taskfile tf; char cdb[] = { GPCMD_GET_CONFIGURATION, 2, /* only 1 feature descriptor requested */ 0, 3, /* 3, removable medium feature */ @@ -62,6 +62,7 @@ static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev) 0, 0, 0, }; + ata_tf_init(dev, &tf); tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf.command = ATA_CMD_PACKET; tf.protocol = ATAPI_PROT_PIO; -- cgit v0.10.2 From 9bbb1b0e2a83c5b3922a050acc932ee3004e85b6 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 23 Jun 2013 01:39:39 +0400 Subject: AHCI: use ATA_BUSY ahci_hardreset() and ahci_p5wdh_hardreset() use bare numbers for the BSY bit of the ATA status register, despite it's #define'd in . Signed-off-by: Sergei Shtylyov Signed-off-by: Tejun Heo diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index da45325..8db82d3 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -583,7 +583,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(link->device, &tf); - tf.command = 0x80; + tf.command = ATA_BUSY; ata_tf_to_fis(&tf, 0, 0, d2h_fis); rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 64c3f1f..c240e4a 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1413,7 +1413,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class, /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(link->device, &tf); - tf.command = 0x80; + tf.command = ATA_BUSY; ata_tf_to_fis(&tf, 0, 0, d2h_fis); rc = sata_link_hardreset(link, timing, deadline, &online, -- cgit v0.10.2