[SCSI] mpt2sas: Improvement were made to better protect the sas_device, raid_device, and expander_device lists

There were possible race conditions surrounding reading an object
from the link list while from another context in the driver was
removing it. The nature of this enhancement is to rearrange locking
so the link lists are better protected.

Change set:
(1) numerous routines were rearranged so spin locks are held through
the entire time a link list object is being read from or written to.
(2) added new routines for object deletion from link list.  Thus ensuring
lock was held during the deletion of the link list object, then and memory
for object freed outside the lock. The memory was freed outside the lock
so driver had access to device object info which was required for
notifying the scsi mid layer that a device was getting deleted.
(3) added the ioc->blocking_handles parameter.  This is a bitmask used
to identify which devices need blocking when there is device loss.  This was
introduced so that lock can be held for the entire time traversing the link
list objects, and the bitmask was set to indicate which device handles need
blocking. Oustide the lock the ioc->blocking_handles bitmask is traversed,
with the respective device handle the scsi mid layer is called for moving
devices into blocking state.

Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index c7459fd..5a0dc30 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -720,6 +720,7 @@
  * @io_missing_delay: time for IO completed by fw when PDR enabled
  * @device_missing_delay: time for device missing by fw when PDR enabled
  * @sas_id : used for setting volume target IDs
+ * @blocking_handles: bitmask used to identify which devices need blocking
  * @pd_handles : bitmask for PD handles
  * @pd_handles_sz : size of pd_handle bitmask
  * @config_page_sz: config page size
@@ -889,7 +890,7 @@
 	u8		io_missing_delay;
 	u16		device_missing_delay;
 	int		sas_id;
-
+	void		*blocking_handles;
 	void		*pd_handles;
 	u16		pd_handles_sz;
 
@@ -1058,7 +1059,8 @@
 void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
 void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
 void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
-void mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
+void mpt2sas_device_remove_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
+		u64 sas_address);
 struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc,
     u16 handle);
 struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER