Skip to contentSkip to conversation

libsas: fix definition of wideport, include local sas address

PATCH In review Dan Williams 2 participants 4 messages Oct 1, 2010 – Oct 5, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 libsas: fix definition of wideport, include local sas address

To date libsas has only looked at the attached sas address when determining the formation of wide ports. The specification and some hardware expects that phys with different addresses will not form a wide port unless the local peer phys also match each other. Introduce a flag to select stricter behavior at sas_register_ha() time. The flag can be dropped once it is known that all libsas users expect the same behavior.

Current drivers just initialize this field to zero and get the traditional behavior.

---
 drivers/scsi/libsas/sas_port.c |   18 +++++++++++++-----
 include/scsi/libsas.h          |    2 ++
 2 files changed, 15 insertions(+), 5 deletions(-)
drivers/scsi/libsas/sas_port.c +13 -5
index fe8b74c..5257fdf 100644
@@ -28,6 +28,17 @@
 #include <scsi/scsi_transport_sas.h>
 #include "../scsi_sas_internal.h"
 
+static bool phy_is_wideport_member(struct asd_sas_port *port, struct asd_sas_phy *phy)
+{
+	struct sas_ha_struct *sas_ha = phy->ha;
+
+	if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
+		   SAS_ADDR_SIZE) != 0 || (sas_ha->strict_wide_ports &&
+	     memcmp(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE) != 0))
+		return false;
+	return true;
+}
+
 /**
  * sas_form_port -- add this phy to a port
  * @phy: the phy of interest
@@ -45,8 +56,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
 	unsigned long flags;
 
 	if (port) {
-		if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
-			   SAS_ADDR_SIZE) != 0)
+		if (!phy_is_wideport_member(port, phy))
 			sas_deform_port(phy);
 		else {
 			SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n",
@@ -62,9 +72,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
 		port = sas_ha->sas_port[i];
 		spin_lock(&port->phy_list_lock);
 		if (*(u64 *) port->sas_addr &&
-		    memcmp(port->attached_sas_addr,
-			   phy->attached_sas_addr, SAS_ADDR_SIZE) == 0 &&
-		    port->num_phys > 0) {
+		    phy_is_wideport_member(port, phy) && port->num_phys > 0) {
 			/* wide port */
 			SAS_DPRINTK("phy%d matched wide port%d\n", phy->id,
 				    port->id);
include/scsi/libsas.h +2 -0
index 3dec194..5173bba 100644
@@ -361,6 +361,8 @@ struct sas_ha_struct {
 	/* The class calls this to send a task for execution. */
 	int lldd_max_execute_num;
 	int lldd_queue_size;
+	int strict_wide_ports; /* both sas_addr and attached_sas_addr must match
+				* their siblings when forming wide ports */
 
 	/* LLDD calls these to notify the class of an event. */
 	void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event);
#1 lore raw

To date libsas has only looked at the attached sas address when determining the formation of wide ports. The specification and some hardware expects that phys with different addresses will not form a wide port unless the local peer phys also match each other. Introduce a flag to select stricter behavior at sas_register_ha() time. The flag can be dropped once it is known that all libsas users expect the same behavior.

Current drivers just initialize this field to zero and get the traditional behavior.
[Jack] I prefer to use the new definition of wideport to the default.

---
 drivers/scsi/libsas/sas_port.c |   18 +++++++++++++-----
 include/scsi/libsas.h          |    2 ++
 2 files changed, 15 insertions(+), 5 deletions(-)
drivers/scsi/libsas/sas_port.c +1 -0
index fe8b74c..5257fdf 100644
@@ -28,6 +28,17 @@
 #include <scsi/scsi_transport_sas.h>
 #include "../scsi_sas_internal.h"
 
+static bool phy_is_wideport_member(struct asd_sas_port *port, struct

asd_sas_phy *phy)
+{
+ struct sas_ha_struct *sas_ha = phy->ha;
+
+ if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
+ SAS_ADDR_SIZE) != 0 || (sas_ha->strict_wide_ports &&
+ memcmp(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE) != 0))
+ return false;
+ return true;
+}
+
/**
* sas_form_port -- add this phy to a port
* @phy: the phy of interest
@@ -45,8 +56,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
unsigned long flags;

if (port) {
- if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
- SAS_ADDR_SIZE) != 0)
+ if (!phy_is_wideport_member(port, phy))
sas_deform_port(phy);
else {
SAS_DPRINTK("%s: phy%d belongs to port%d
already(%d)!\n",
@@ -62,9 +72,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
port = sas_ha->sas_port[i]; spin_lock(&port->phy_list_lock);
if (*(u64 *) port->sas_addr &&

-		    memcmp(port->attached_sas_addr,
-			   phy->attached_sas_addr, SAS_ADDR_SIZE) == 0 &&
-		    port->num_phys > 0) {
+		    phy_is_wideport_member(port, phy) && port->num_phys > 0)

{
/* wide port */
SAS_DPRINTK("phy%d matched wide port%d\n", phy->id,
port->id);

include/scsi/libsas.h +1 -0
index 3dec194..5173bba 100644
@@ -361,6 +361,8 @@ struct sas_ha_struct {
 	/* The class calls this to send a task for execution. */
 	int lldd_max_execute_num;
 	int lldd_queue_size;
+	int strict_wide_ports; /* both sas_addr and attached_sas_addr must

match
+ * their siblings when forming wide ports */

/* LLDD calls these to notify the class of an event. */ void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event);
[Jack] I cann't find where to judge the flag to chose which definition to use?

#2 lore raw
Quoted 11 lines · Jack Wang

To date libsas has only looked at the attached sas address when determining the formation of wide ports.  The specification and some hardware expects that phys with different addresses will not form a wide port unless the local peer phys also match each other.  Introduce a flag to select stricter behavior at sas_register_ha() time.  The flag can be dropped once it is known that all libsas users expect the same behavior.

Current drivers just initialize this field to zero and get the traditional behavior.
[Jack] I prefer to use the new definition of wideport to the default.

Ok, when mvsas and aic94xx are also ready for this change we can just make this the default and kill the flag.

Quoted 2 lines

[Jack] I cann't find where to judge the flag to chose which definition to use?

I am not clear on the question. phy_is_wideport_member() should be the only location that needs to read this flag. The driver just sets it to 1 before calling sas_register_ha() and then assumes the strict definition is in effect for the lifetime of the driver instance.

--
Dan
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#3 lore raw

Re: [PATCH] libsas: fix definition of wideport, include local sas address

Quoted 11 lines · Jack Wang

To date libsas has only looked at the attached sas address when determining the formation of wide ports.  The specification and some hardware expects that phys with different addresses will not form a wide port unless the local peer phys also match each other.  Introduce a flag to select stricter behavior at sas_register_ha() time.  The flag can be dropped once it is known that all libsas users expect the same behavior.

Current drivers just initialize this field to zero and get the traditional behavior.
[Jack] I prefer to use the new definition of wideport to the default.

Ok, when mvsas and aic94xx are also ready for this change we can just make this the default and kill the flag.

Quoted 2 lines

[Jack] I cann't find where to judge the flag to chose which definition to use?

I am not clear on the question. phy_is_wideport_member() should be the only location that needs to read this flag. The driver just sets it to 1 before calling sas_register_ha() and then assumes the strict definition is in effect for the lifetime of the driver instance. [Jack] Ohh, I miss something in the patch. It's ok for me. Thanks for Explanation.

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html