Re: libata pmp support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Izik Weksler wrote:
> Tejun,
> 
> If you're sending the patch please send it to this address.

Okay, please test the attached patch and please cc
linux-ide@xxxxxxxxxxxxxxx when replying.  Thanks.

-- 
tejun
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 06f212f..d838bdd 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -44,6 +44,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <linux/libata.h>
+#include <linux/dmi.h>
 
 #define DRV_NAME	"ahci"
 #define DRV_VERSION	"2.3"
@@ -1631,6 +1632,31 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
 }
 #endif
 
+static void ahci_port_mark_nosrst(struct ata_port *ap)
+{
+	static struct dmi_system_id sysids[] = {
+		{
+			.ident = "P5W DH Deluxe",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "ASUSTEK COMPUTER INC"),
+				DMI_MATCH(DMI_PRODUCT_NAME, "P5W DH Deluxe"),
+			},
+		},
+		{ }
+	};
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+
+	/* The second port of the PCI device 00:1f.2 is connected to a
+	 * SIMG PMP which pukes on SRST.
+	 */
+	if (pdev->bus->number == 0 && pdev->devfn == PCI_DEVFN(0x1f, 2) &&
+	    ap->port_no == 1 && dmi_check_system(sysids)) {
+		dev_printk(KERN_INFO, &pdev->dev,
+			   "enabling ASUS on-board PMP workaround\n");
+		ap->flags |= ATA_FLAG_NO_SRST;
+	}
+}
+
 static int ahci_port_start(struct ata_port *ap)
 {
 	struct device *dev = ap->host->dev;
@@ -1639,6 +1665,8 @@ static int ahci_port_start(struct ata_port *ap)
 	dma_addr_t mem_dma;
 	int rc;
 
+	ahci_port_mark_nosrst(ap);
+
 	pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
 	if (!pp)
 		return -ENOMEM;
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index ac6ceed..c51fa7f 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1759,9 +1759,12 @@ static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
 	return 0;
 }
 
-static int ata_eh_followup_srst_needed(int rc, int classify,
+static int ata_eh_followup_srst_needed(struct ata_port *ap,
+				       int rc, int classify,
 				       const unsigned int *classes)
 {
+	if (ap->flags & ATA_FLAG_NO_SRST)
+		return 0;
 	if (rc == -EAGAIN)
 		return 1;
 	if (rc != 0)
@@ -1792,7 +1795,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
 	 */
 	action = ehc->i.action;
 	ehc->i.action &= ~ATA_EH_RESET_MASK;
-	if (softreset && (!hardreset || (!sata_set_spd_needed(ap) &&
+	if (softreset && (!hardreset || (!(ap->flags & ATA_FLAG_NO_SRST) &&
+					 !sata_set_spd_needed(ap) &&
 					 !(action & ATA_EH_HARDRESET))))
 		ehc->i.action |= ATA_EH_SOFTRESET;
 	else
@@ -1855,7 +1859,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
 	rc = ata_do_reset(ap, reset, classes, deadline);
 
 	if (reset == hardreset &&
-	    ata_eh_followup_srst_needed(rc, classify, classes)) {
+	    ata_eh_followup_srst_needed(ap, rc, classify, classes)) {
 		/* okay, let's do follow-up softreset */
 		reset = softreset;
 
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 41978a5..8f98689 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -177,6 +177,7 @@ enum {
 	ATA_FLAG_IGN_SIMPLEX	= (1 << 15), /* ignore SIMPLEX */
 	ATA_FLAG_NO_IORDY	= (1 << 16), /* controller lacks iordy */
 	ATA_FLAG_ACPI_SATA	= (1 << 17), /* need native SATA ACPI layout */
+	ATA_FLAG_NO_SRST	= (1 << 18), /* avoid softreset */
 
 	/* The following flag belongs to ap->pflags but is kept in
 	 * ap->flags because it's referenced in many LLDs and will be

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux