summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-06-23 23:44:52 -0700
committerDan Williams <dan.j.williams@intel.com>2011-07-03 04:04:51 -0700
commit4cffe13e0dfd00f90c86b0153c751dab61a1bf1d (patch)
treec9d04a30f845dcaa0eb750405e63bb43ca5657f1
parent7cafbf1bd56be44038148bb8f733ea6e6a6a2d53 (diff)
downloadlwn-4cffe13e0dfd00f90c86b0153c751dab61a1bf1d.tar.gz
lwn-4cffe13e0dfd00f90c86b0153c751dab61a1bf1d.zip
isci: fix frame received locking
Updates to the frame_rcvd before need to be atomic with respect to when they are evaluated by libsas. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/scsi/isci/phy.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c
index 93a401dfbd30..c01d76210aa2 100644
--- a/drivers/scsi/isci/phy.c
+++ b/drivers/scsi/isci/phy.c
@@ -893,6 +893,7 @@ enum sci_status scic_sds_phy_frame_handler(struct scic_sds_phy *sci_phy,
enum scic_sds_phy_states state = sci_phy->sm.current_state_id;
struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;
enum sci_status result;
+ unsigned long flags;
switch (state) {
case SCI_PHY_SUB_AWAIT_IAF_UF: {
@@ -911,7 +912,9 @@ enum sci_status scic_sds_phy_frame_handler(struct scic_sds_phy *sci_phy,
if (iaf.frame_type == 0) {
u32 state;
+ spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
memcpy(&iphy->frame_rcvd.iaf, &iaf, sizeof(iaf));
+ spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
if (iaf.smp_tport) {
/* We got the IAF for an expander PHY go to the final
* state since there are no power requirements for
@@ -954,9 +957,11 @@ enum sci_status scic_sds_phy_frame_handler(struct scic_sds_phy *sci_phy,
frame_index,
(void **)&fis_frame_data);
+ spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
scic_sds_controller_copy_sata_response(&iphy->frame_rcvd.fis,
frame_header,
fis_frame_data);
+ spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
/* got IAF we can now go to the await spinup semaphore state */
sci_change_state(&sci_phy->sm, SCI_PHY_SUB_FINAL);