Skip to contentSkip to conversation

mpt fusion: mptsas - do not use ioc->handle to locate hba portinfo structure

PATCH New Michael Reed 1 participant 1 message Mar 20, 2008

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

PATCH 1/1 mpt fusion: mptsas - do not use ioc->handle to locate hba portinfo structure

While performing hardware raid reset testing via the raid's client, I noticed that sometimes, following the reset, that there would be more raid targets in the lsscsi output than there actually were raid targets. I tracked this down to the following issue.

Fusion cannot always find the mptsas_portinfo structure for the hba because it uses the handle stored in ioc->handle to locate it. The problem is that the firmware can change the handle associated with the hba when h/w raid is reset (via the raid client). When this happens, the driver will allocate another mptsas_portinfo structure and link it into the chain of said structures. This ultimately causes confusion within the driver resulting in targets not being removed when they should be.

Eric Moore pointed out that the hba's portinfo structure is always the first structure on the sas_topology list. This patch modifies mptsas.c to access the hba's portinfo structure by taking the first structure on said list.

Applies to 2.6.25-rc6-git5

drivers/message/fusion/mptbase.h +0 -1
@@ -693,7 +693,6 @@ typedef struct _MPT_ADAPTER
 	struct mutex		 sas_discovery_mutex;
 	u8			 sas_discovery_runtime;
 	u8			 sas_discovery_ignore_events;
-	u16			 handle;
 	int			 sas_index; /* index refrencing */
 	MPT_SAS_MGMT		 sas_mgmt;
 	struct work_struct	 sas_persist_task;
drivers/message/fusion/mptsas.c +17 -5
@@ -230,6 +230,20 @@ static inline MPT_ADAPTER *rphy_to_ioc(s
 	return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
 }
 
+static struct mptsas_portinfo *
+mptsas_get_hba_portinfo(MPT_ADAPTER *ioc)
+{
+        struct list_head	*head = &ioc->sas_topology;
+	struct mptsas_portinfo	*pi=NULL;
+
+	/* always the first entry on sas_topology list */
+ 
+	if (!list_empty(head))
+		pi = list_entry(head->next, struct mptsas_portinfo, list);
+
+	return pi;
+}
+
 /*
  * mptsas_find_portinfo_by_handle
  *
@@ -1290,7 +1304,7 @@ static int mptsas_smp_handler(struct Scs
 		struct mptsas_portinfo *port_info;
 
 		mutex_lock(&ioc->sas_topology_mutex);
-		port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
+		port_info = mptsas_get_hba_portinfo(ioc);
 		if (port_info && port_info->phy_info)
 			sas_address =
 				port_info->phy_info[0].phy->identify.sas_address;
@@ -2028,8 +2042,7 @@ static int mptsas_probe_one_phy(struct d
 			int i;
 
 			mutex_lock(&ioc->sas_topology_mutex);
-			port_info = mptsas_find_portinfo_by_handle(ioc,
-								   ioc->handle);
+			port_info = mptsas_get_hba_portinfo(ioc);
 			mutex_unlock(&ioc->sas_topology_mutex);
 
 			for (i = 0; i < port_info->num_phys; i++)
@@ -2099,8 +2112,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
 
 	mptsas_sas_io_unit_pg1(ioc);
 	mutex_lock(&ioc->sas_topology_mutex);
-	ioc->handle = hba->phy_info[0].handle;
-	port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
+	port_info = mptsas_get_hba_portinfo(ioc);
 	if (!port_info) {
 		port_info = hba;
 		list_add_tail(&port_info->list, &ioc->sas_topology);