aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid/megaraid_sas_fusion.c
diff options
context:
space:
mode:
authorSumit Saxena <sumit.saxena@avagotech.com>2016-01-28 10:44:25 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2016-02-23 21:27:02 -0500
commit8f67c8c518f324874e8caf93d1f4468d25754333 (patch)
tree4dcc442e24778215d60f734e71c26478c120e03c /drivers/scsi/megaraid/megaraid_sas_fusion.c
parentde983561e6de5c62a6b4200f8304267d7a5cc872 (diff)
megaraid_sas: Fix for IO failing post OCR in SRIOV environment
Driver assumes that VFs always have peers present whenever they have same LD IDs. But this is not the case. This patch handles the above mentioned by explicitly checking for a peer before making HA/non-HA path decision. Signed-off-by: Uday Lingala <uday.lingala@avagotech.com> Signed-off-by: Sumit Saxena <sumit.saxena@avagotech.com> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/megaraid/megaraid_sas_fusion.c')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index be9c3f1b9def..d9d0029fb1b0 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -3325,27 +3325,37 @@ out:
3325 return ret; 3325 return ret;
3326} 3326}
3327 3327
3328/*SRIOV get other instance in cluster if any*/
3329struct megasas_instance *megasas_get_peer_instance(struct megasas_instance *instance)
3330{
3331 int i;
3332
3333 for (i = 0; i < MAX_MGMT_ADAPTERS; i++) {
3334 if (megasas_mgmt_info.instance[i] &&
3335 (megasas_mgmt_info.instance[i] != instance) &&
3336 megasas_mgmt_info.instance[i]->requestorId &&
3337 megasas_mgmt_info.instance[i]->peerIsPresent &&
3338 (memcmp((megasas_mgmt_info.instance[i]->clusterId),
3339 instance->clusterId, MEGASAS_CLUSTER_ID_SIZE) == 0))
3340 return megasas_mgmt_info.instance[i];
3341 }
3342 return NULL;
3343}
3344
3328/* Check for a second path that is currently UP */ 3345/* Check for a second path that is currently UP */
3329int megasas_check_mpio_paths(struct megasas_instance *instance, 3346int megasas_check_mpio_paths(struct megasas_instance *instance,
3330 struct scsi_cmnd *scmd) 3347 struct scsi_cmnd *scmd)
3331{ 3348{
3332 int i, j, retval = (DID_RESET << 16); 3349 struct megasas_instance *peer_instance = NULL;
3333 3350 int retval = (DID_RESET << 16);
3334 if (instance->mpio && instance->requestorId) { 3351
3335 for (i = 0 ; i < MAX_MGMT_ADAPTERS ; i++) 3352 if (instance->peerIsPresent) {
3336 for (j = 0 ; j < MAX_LOGICAL_DRIVES; j++) 3353 peer_instance = megasas_get_peer_instance(instance);
3337 if (megasas_mgmt_info.instance[i] && 3354 if ((peer_instance) &&
3338 (megasas_mgmt_info.instance[i] != instance) && 3355 (atomic_read(&peer_instance->adprecovery) ==
3339 megasas_mgmt_info.instance[i]->mpio && 3356 MEGASAS_HBA_OPERATIONAL))
3340 megasas_mgmt_info.instance[i]->requestorId 3357 retval = (DID_NO_CONNECT << 16);
3341 &&
3342 (megasas_mgmt_info.instance[i]->ld_ids[j]
3343 == scmd->device->id)) {
3344 retval = (DID_NO_CONNECT << 16);
3345 goto out;
3346 }
3347 } 3358 }
3348out:
3349 return retval; 3359 return retval;
3350} 3360}
3351 3361