RE: [PATCH] ahci: add Marvell support (WIP)

From: George T. Joseph \(development\)
Date: Mon May 21 2007 - 11:27:23 EST


Hi Jeff,

Two issues with the patch...

msi has to be disabled for the Marvell or the driver load will throw a
"nobody cared" message and eventually hang before discovering all the
drives.

Light I/O works fine but heavy I/O generates
"exception Emask 0x0 Sact 0xb Serr 0x0 action 0x2 frozen"
Then softreset and identify failures.
Adding AHCI_FLAG_NO_NCQ to the flags fixes this.

I've been running with both these changes over your original patch for a
few months now with no problems. This is on a very heavily used 4 drive
mdraid10 array.

Thanks for the work on the patch...george


> -----Original Message-----
> From: linux-ide-owner@xxxxxxxxxxxxxxx
> [mailto:linux-ide-owner@xxxxxxxxxxxxxxx] On Behalf Of Jeff Garzik
> Sent: Friday, May 18, 2007 11:47 PM
> To: linux-ide@xxxxxxxxxxxxxxx
> Cc: LKML
> Subject: [PATCH] ahci: add Marvell support (WIP)
>
>
> This is the work-in-progress for supporting the newer Marvell
> PATA/SATA
> chips like the 6145.
>
> SATA support works, but PATA support is not implemented at all.
> There is some temporary code that makes sure the PATA port is
> disabled,
> if enabled.
>
> This can be found in the 'mv-ahci' branch of
> git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
>
> [libata] ahci: Marvell code build fix
> [libata] AHCI: get Marvell SATA going (PATA portion of
> chip not supported)
>
> drivers/ata/ahci.c | 60
> +++++++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 56 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
> index e00e1b9..d2d15b2 100644
> --- a/drivers/ata/ahci.c
> +++ b/drivers/ata/ahci.c
> @@ -81,6 +81,7 @@ enum {
> board_ahci_vt8251 = 2,
> board_ahci_ign_iferr = 3,
> board_ahci_sb600 = 4,
> + board_ahci_mv = 5,
>
> /* global controller registers */
> HOST_CAP = 0x00, /* host capabilities */
> @@ -170,6 +171,7 @@ enum {
> AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore
> IRQ_IF_ERR */
> AHCI_FLAG_HONOR_PI = (1 << 26), /* honor
> PORTS_IMPL */
> AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore
> SERR_INTERNAL */
> + AHCI_FLAG_MV_PATA = (1 << 28), /* PATA port */
>
> AHCI_FLAG_COMMON = ATA_FLAG_SATA |
> ATA_FLAG_NO_LEGACY |
> ATA_FLAG_MMIO |
> ATA_FLAG_PIO_DMA |
> @@ -359,6 +361,17 @@ static const struct ata_port_info
> ahci_port_info[] = {
> .udma_mask = 0x7f, /* udma0-6 ; FIXME */
> .port_ops = &ahci_ops,
> },
> + /* board_ahci_mv */
> + {
> + .sht = &ahci_sht,
> + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
> + ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
> + ATA_FLAG_SKIP_D2H_BSY |
> AHCI_FLAG_HONOR_PI |
> + AHCI_FLAG_MV_PATA,
> + .pio_mask = 0x1f, /* pio0-4 */
> + .udma_mask = 0x7f, /* udma0-6 ; FIXME */
> + .port_ops = &ahci_ops,
> + },
> };
>
> static const struct pci_device_id ahci_pci_tbl[] = {
> @@ -430,6 +443,9 @@ static const struct pci_device_id
> ahci_pci_tbl[] = {
> { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
> { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
>
> + /* Marvell */
> + { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv },
> /* 6145 */
> +
> /* Generic, PCI class code for AHCI */
> { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
> PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
> @@ -455,11 +471,17 @@ static inline int ahci_nr_ports(u32 cap)
> return (cap & 0x1f) + 1;
> }
>
> -static inline void __iomem *ahci_port_base(struct ata_port *ap)
> +static inline void __iomem *__ahci_port_base(struct ata_host *host,
> + unsigned int port_no)
> {
> - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
> + void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
>
> - return mmio + 0x100 + (ap->port_no * 0x80);
> + return mmio + 0x100 + (port_no * 0x80);
> +}
> +
> +static inline void __iomem *ahci_port_base(struct ata_port *ap)
> +{
> + return __ahci_port_base(ap->host, ap->port_no);
> }
>
> /**
> @@ -502,6 +524,20 @@ static void
> ahci_save_initial_config(struct pci_dev *pdev,
> hpriv->saved_port_map = port_map;
> }
>
> + /*
> + * Temporary Marvell 6145 hack: PATA port presence
> + * is asserted through the standard AHCI port
> + * presence register, as bit 4 (counting from 0)
> + */
> + if (pi->flags & AHCI_FLAG_MV_PATA) {
> + dev_printk(KERN_ERR, &pdev->dev,
> + "MV_AHCI HACK: port_map %x -> %x\n",
> + hpriv->port_map,
> + hpriv->port_map & 0xf);
> +
> + port_map &= 0xf;
> + }
> +
> /* cross check port_map and cap.n_ports */
> if (pi->flags & AHCI_FLAG_HONOR_PI) {
> u32 tmp_port_map = port_map;
> @@ -785,14 +821,27 @@ static void ahci_init_controller(struct
> ata_host *host)
> {
> struct pci_dev *pdev = to_pci_dev(host->dev);
> void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
> + void __iomem *port_mmio;
> int i, rc;
> u32 tmp;
>
> + if (host->ports[0]->flags & AHCI_FLAG_MV_PATA) {
> + port_mmio = __ahci_port_base(host, 4);
> +
> + writel(0, port_mmio + PORT_IRQ_MASK);
> +
> + /* clear port IRQ */
> + tmp = readl(port_mmio + PORT_IRQ_STAT);
> + VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
> + if (tmp)
> + writel(tmp, port_mmio + PORT_IRQ_STAT);
> + }
> +
> for (i = 0; i < host->n_ports; i++) {
> struct ata_port *ap = host->ports[i];
> - void __iomem *port_mmio = ahci_port_base(ap);
> const char *emsg = NULL;
>
> + port_mmio = ahci_port_base(ap);
> if (ata_port_is_dummy(ap))
> continue;
>
> @@ -807,6 +856,9 @@ static void ahci_init_controller(struct
> ata_host *host)
> VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
> writel(tmp, port_mmio + PORT_SCR_ERR);
>
> + /* select the IRQ events we're interested in */
> + writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
> +
> /* clear port IRQ */
> tmp = readl(port_mmio + PORT_IRQ_STAT);
> VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
> -
> To unsubscribe from this list: send the line "unsubscribe
> linux-ide" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/