Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3446

kernel-2.6.18-194.11.1.el5.src.rpm

From: David Milburn <dmilburn@redhat.com>
Date: Fri, 12 Jun 2009 10:14:41 -0500
Subject: [scsi] libsas: use the supplied address for SATA devices
Message-id: 20090612151441.GB5713@dhcp-210.hsv.redhat.com
O-Subject: [RHEL5.4 PATCH] libsas: use the supplied address for SATA devices
Bugzilla: 494658
RH-Acked-by: Jeff Garzik <jgarzik@redhat.com>
RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com>
RH-Acked-by: Stefan Assmann <sassmann@redhat.com>

Under RHEL5 running aic94xx driver with AIC-9410W SAS/SATA
Host adapter, libsas continually adds/removes a phy to/from
a port and the system will never boot up. After a phy has
been originally added, subsequent calls to sas_form_port()
compare a port's attached_sas_addr to a phy's attached_sas_addr,
this always fails causing sas_deform_port() to remove the phy
from the port. The mismatch happens during discovery since
the port's attached_sas_addr is updated based upon the WWN
field returned by the IDENTIFY DEVICE (0xec) command.

This is a backport of this upstream commit:

commit a29c05153630b2cd5ea078c97c0abe084cd830d8

This resolves BZ 494658, Stratus has verified a -152.el5
test kernel attached with this patch, please review and ACK.

Thanks,
David

diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 1a51cec..febb056 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -241,12 +241,12 @@ static void sas_ata_phy_reset(struct ata_port *ap)
 	struct domain_device *dev = ap->private_data;
 	struct sas_internal *i =
 		to_sas_internal(dev->port->ha->core.shost->transportt);
-	int res = 0;
+	int res = TMF_RESP_FUNC_FAILED;
 
 	if (i->dft->lldd_I_T_nexus_reset)
 		res = i->dft->lldd_I_T_nexus_reset(dev);
 
-	if (res)
+	if (res != TMF_RESP_FUNC_COMPLETE)
 		SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __FUNCTION__);
 
 	switch (dev->sata_dev.command_set) {
@@ -653,21 +653,6 @@ out:
 	return res;
 }
 
-static void sas_sata_propagate_sas_addr(struct domain_device *dev)
-{
-	unsigned long flags;
-	struct asd_sas_port *port = dev->port;
-	struct asd_sas_phy  *phy;
-
-	BUG_ON(dev->parent);
-
-	memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
-	spin_lock_irqsave(&port->phy_list_lock, flags);
-	list_for_each_entry(phy, &port->phy_list, port_phy_el)
-		memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
-	spin_unlock_irqrestore(&port->phy_list_lock, flags);
-}
-
 #define ATA_IDENTIFY_DEV         0xEC
 #define ATA_IDENTIFY_PACKET_DEV  0xA1
 #define ATA_SET_FEATURES         0xEF
@@ -725,26 +710,6 @@ static int sas_discover_sata_dev(struct domain_device *dev)
 			goto out_err;
 	}
 cont1:
-	/* Get WWN */
-	if (dev->port->oob_mode != SATA_OOB_MODE) {
-		memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr,
-		       SAS_ADDR_SIZE);
-	} else if (dev->sata_dev.command_set == ATA_COMMAND_SET &&
-		   (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000)
-		   == 0x5000) {
-		int i;
-
-		for (i = 0; i < 4; i++) {
-			dev->sas_addr[2*i] =
-	     (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8;
-			dev->sas_addr[2*i+1] =
-	      le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF;
-		}
-	}
-	sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
-	if (!dev->parent)
-		sas_sata_propagate_sas_addr(dev);
-
 	/* XXX Hint: register this SATA device with SATL.
 	   When this returns, dev->sata_dev->lu is alive and
 	   present.
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index 90f1b48..b00466c 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -92,9 +92,6 @@ static void sas_form_port(struct asd_sas_phy *phy)
 	if (!port->phy)
 		port->phy = phy->phy;
 
-	SAS_DPRINTK("phy%d added to port%d, phy_mask:0x%x\n", phy->id,
-		    port->id, port->phy_mask);
-
 	if (*(u64 *)port->attached_sas_addr == 0) {
 		port->class = phy->class;
 		memcpy(port->attached_sas_addr, phy->attached_sas_addr,
@@ -115,6 +112,11 @@ static void sas_form_port(struct asd_sas_phy *phy)
 	}
 	sas_port_add_phy(port->port, phy->phy);
 
+	SAS_DPRINTK("%s added to %s, phy_mask:0x%x (%16llx)\n",
+		    phy->phy->dev.bus_id, port->port->dev.bus_id,
+		    port->phy_mask,
+		    SAS_ADDR(port->attached_sas_addr));
+
 	if (port->port_dev)
 		port->port_dev->pathways = port->num_phys;
 
@@ -245,12 +247,11 @@ void sas_porte_hard_reset(void *data)
 static void sas_init_port(struct asd_sas_port *port,
 			  struct sas_ha_struct *sas_ha, int i)
 {
+	memset(port, 0, sizeof(*port));
 	port->id = i;
 	INIT_LIST_HEAD(&port->dev_list);
 	spin_lock_init(&port->phy_list_lock);
 	INIT_LIST_HEAD(&port->phy_list);
-	port->num_phys = 0;
-	port->phy_mask = 0;
 	port->ha = sas_ha;
 
 	spin_lock_init(&port->dev_list_lock);