summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Reed <mdr@sgi.com>2008-03-20 23:32:05 +0100
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-07 19:19:00 +0200
commit7748369f49d428e558c519ed344d3005d38347b7 (patch)
tree37a8bcdbd147d11bf1d93c2cb2a0ac3404e4b0a2
parent[SCSI] qla4xxx: fix scsi command completion, lun reset and target reset code (diff)
downloadlinux-7748369f49d428e558c519ed344d3005d38347b7.tar.xz
linux-7748369f49d428e558c519ed344d3005d38347b7.zip
[SCSI] 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. Signed-off-by: Michael Reed <mdr@sgi.com> Acked-by: "Moore, Eric" <Eric.Moore@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/message/fusion/mptbase.h1
-rw-r--r--drivers/message/fusion/mptsas.c22
2 files changed, 17 insertions, 6 deletions
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 0041ab3e5e80..a8f617447d22 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -695,7 +695,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;
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 78734e25edd5..468480771f13 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -230,6 +230,20 @@ static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
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 Scsi_Host *shost, struct sas_rphy *rphy,
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 device *dev,
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);