Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 159

kernel-2.6.18-238.el5.src.rpm

From: David Milburn <dmilburn@redhat.com>
Date: Wed, 14 Jul 2010 16:20:08 -0400
Subject: [ata] ahci, pata_marvell: fixup competition for PATA port
Message-id: <20100714162008.GA8616@localhost.localdomain>
Patchwork-id: 26893
O-Subject: [RHEL5.6 PATCH] ahci, pata_marvell: fixup competition for PATA port
Bugzilla: 237372
RH-Acked-by: Jeff Garzik <jgarzik@redhat.com>

This patch creates an ahci module param which by defaults allows
the pata_marvell driver to control the PATA port on the Marvell
6121 and 6145 controllers. The module param can be set to allow
the ahci driver to control the SATA ports on the Marvell controllers.

This is consistent with RHEL6 and upstream, and has been verified
by reporter. This resolves BZ 237372, please review and ACK.

commit 5b66c829bf5c65663b2f68ee6b42f6e834cd39cd
Author: Alan Cox <alan@lxorguk.ukuu.org.uk>
Date:   Wed Sep 3 14:48:34 2008 +0100

    ahci, pata_marvell: play nicely together

commit 17248461cb66103b87ff03bdee34aa61035cc93e
Author: Tejun Heo <tj@kernel.org>
Date:   Fri Aug 29 16:03:59 2008 +0200

    ahci: disable PMP for marvell ahcis

commit cb6643e1c38b6bd5c1594f0a45d8cf6943a6f934
Author: Christoph Egger <siccegge@stud.informatik.uni-erlangen.de>
Date:   Fri Feb 5 16:26:35 2010 +0100

    [libata] pata_marvell: CONFIG_AHCI is really CONFIG_SATA_AHCI

Thanks,
David

 drivers/ata/Kconfig        |    6 +++-
 drivers/ata/ahci.c         |   19 +++++++++++++++-
 drivers/ata/pata_marvell.c |   51 ++++++++++++++++++++++++++++++++-----------
 3 files changed, 60 insertions(+), 16 deletions(-)

Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index a30c655..4ee9189 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -445,8 +445,10 @@ config PATA_MARVELL
 	tristate "Marvell PATA support via legacy mode"
 	depends on PCI
 	help
-	  This option enables limited support for the Marvell 88SE6145 ATA
-	  controller.
+	  This option enables limited support for the Marvell 88SE61xx ATA
+	  controllers. If you wish to use only the SATA ports then select
+	  the AHCI driver alone. If you wish to the use the PATA port or
+	  both SATA and PATA include this driver.
 
 	  If unsure, say N.
 
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 91687f5..544e8ad 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -449,7 +449,7 @@ static const struct ata_port_info ahci_port_info[] = {
 	/* board_ahci_mv */
 	{
 		AHCI_HFLAGS	(AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI |
-				 AHCI_HFLAG_MV_PATA),
+				 AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
 		.pio_mask	= 0x1f, /* pio0-4 */
@@ -642,6 +642,15 @@ module_param(ahci_em_messages, int, 0444);
 MODULE_PARM_DESC(ahci_em_messages,
 	"Set AHCI Enclosure Management Message type (0 = disabled, 1 = LED");
 
+#if defined(CONFIG_PATA_MARVELL) || defined(CONFIG_PATA_MARVELL_MODULE)
+static int marvell_enable;
+#else
+static int marvell_enable = 1;
+#endif
+module_param(marvell_enable, int, 0644);
+MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
+
+
 static inline int ahci_nr_ports(u32 cap)
 {
 	return (cap & 0x1f) + 1;
@@ -761,6 +770,8 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
 			   "MV_AHCI HACK: port_map %x -> %x\n",
 			   port_map,
 			   port_map & mv);
+		dev_printk(KERN_ERR, &pdev->dev,
+			  "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n");
 
 		port_map &= mv;
 	}
@@ -2770,6 +2781,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (!printed_version++)
 		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+	/* The AHCI driver can only drive the SATA ports, the PATA driver
+	   can drive them all so if both drivers are selected make sure
+	   AHCI stays out of the way */
+	if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable)
+		return -ENODEV;
+
 	/* acquire resources */
 	rc = pcim_enable_device(pdev);
 	if (rc)
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index 24a011b..50189dd 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -20,29 +20,30 @@
 #include <linux/ata.h>
 
 #define DRV_NAME	"pata_marvell"
-#define DRV_VERSION	"0.1.4"
+#define DRV_VERSION	"0.1.6"
 
 /**
- *	marvell_pre_reset	-	check for 40/80 pin
- *	@link: link
- *	@deadline: deadline jiffies for the operation
+ *	marvell_pata_active	-	check if PATA is active
+ *	@pdev: PCI device
  *
- *	Perform the PATA port setup we need.
+ *	Returns 1 if the PATA port may be active. We know how to check this
+ *	for the 6145 but not the other devices
  */
 
-static int marvell_pre_reset(struct ata_link *link, unsigned long deadline)
+static int marvell_pata_active(struct pci_dev *pdev)
 {
-	struct ata_port *ap = link->ap;
-	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	int i;
 	u32 devices;
 	void __iomem *barp;
-	int i;
 
-	/* Check if our port is enabled */
+	/* We don't yet know how to do this for other devices */
+	if (pdev->device != 0x6145)
+		return 1;	
 
 	barp = pci_iomap(pdev, 5, 0x10);
 	if (barp == NULL)
 		return -ENOMEM;
+
 	printk("BAR5:");
 	for(i = 0; i <= 0x0F; i++)
 		printk("%02X:%02X ", i, ioread8(barp + i));
@@ -51,9 +52,27 @@ static int marvell_pre_reset(struct ata_link *link, unsigned long deadline)
 	devices = ioread32(barp + 0x0C);
 	pci_iounmap(pdev, barp);
 
-	if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
-	    (!(devices & 0x10)))	/* PATA enable ? */
-		return -ENOENT;
+	if (devices & 0x10)
+		return 1;
+	return 0;
+}
+
+/**
+ *	marvell_pre_reset	-	check for 40/80 pin
+ *	@link: link
+ *	@deadline: deadline jiffies for the operation
+ *
+ *	Perform the PATA port setup we need.
+ */
+
+static int marvell_pre_reset(struct ata_link *link, unsigned long deadline)
+{
+	struct ata_port *ap = link->ap;
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+
+	if (pdev->device == 0x6145 && ap->port_no == 0 &&
+		!marvell_pata_active(pdev))	/* PATA enable ? */
+			return -ENOENT;
 
 	return ata_sff_prereset(link, deadline);
 }
@@ -128,6 +147,12 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
 	if (pdev->device == 0x6101)
 		ppi[1] = &ata_dummy_port_info;
 
+#if defined(CONFIG_SATA_AHCI) || defined(CONFIG_SATA_AHCI_MODULE)
+	if (!marvell_pata_active(pdev)) {
+		printk(KERN_INFO DRV_NAME ": PATA port not active, deferring to AHCI driver.\n");
+		return -ENODEV;
+	}
+#endif
 	return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL);
 }