Commit 8f67c8c5 authored by Sumit Saxena's avatar Sumit Saxena Committed by Martin K. Petersen

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: default avatarUday Lingala <uday.lingala@avagotech.com>
Signed-off-by: default avatarSumit Saxena <sumit.saxena@avagotech.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent de983561
...@@ -393,6 +393,7 @@ enum MR_EVT_ARGS { ...@@ -393,6 +393,7 @@ enum MR_EVT_ARGS {
#define SGE_BUFFER_SIZE 4096 #define SGE_BUFFER_SIZE 4096
#define MEGASAS_CLUSTER_ID_SIZE 16
/* /*
* define constants for device list query options * define constants for device list query options
*/ */
...@@ -1227,7 +1228,8 @@ struct megasas_ctrl_info { ...@@ -1227,7 +1228,8 @@ struct megasas_ctrl_info {
*/ */
struct { struct {
#if defined(__BIG_ENDIAN_BITFIELD) #if defined(__BIG_ENDIAN_BITFIELD)
u32 reserved:26; u32 reserved:25;
u32 passive:1;
u32 premiumFeatureMismatch:1; u32 premiumFeatureMismatch:1;
u32 ctrlPropIncompatible:1; u32 ctrlPropIncompatible:1;
u32 fwVersionMismatch:1; u32 fwVersionMismatch:1;
...@@ -1241,11 +1243,12 @@ struct megasas_ctrl_info { ...@@ -1241,11 +1243,12 @@ struct megasas_ctrl_info {
u32 fwVersionMismatch:1; u32 fwVersionMismatch:1;
u32 ctrlPropIncompatible:1; u32 ctrlPropIncompatible:1;
u32 premiumFeatureMismatch:1; u32 premiumFeatureMismatch:1;
u32 reserved:26; u32 passive:1;
u32 reserved:25;
#endif #endif
} cluster; } cluster;
char clusterId[16]; /*7D4h */ char clusterId[MEGASAS_CLUSTER_ID_SIZE]; /*0x7D4 */
struct { struct {
u8 maxVFsSupported; /*0x7E4*/ u8 maxVFsSupported; /*0x7E4*/
u8 numVFsEnabled; /*0x7E5*/ u8 numVFsEnabled; /*0x7E5*/
...@@ -2126,7 +2129,9 @@ struct megasas_instance { ...@@ -2126,7 +2129,9 @@ struct megasas_instance {
char skip_heartbeat_timer_del; char skip_heartbeat_timer_del;
u8 requestorId; u8 requestorId;
char PlasmaFW111; char PlasmaFW111;
char mpio; char clusterId[MEGASAS_CLUSTER_ID_SIZE];
u8 peerIsPresent;
u8 passive;
u16 throttlequeuedepth; u16 throttlequeuedepth;
u8 mask_interrupts; u8 mask_interrupts;
u16 max_chain_frame_sz; u16 max_chain_frame_sz;
......
...@@ -1943,7 +1943,7 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance) ...@@ -1943,7 +1943,7 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance)
writel(MFI_STOP_ADP, &instance->reg_set->doorbell); writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
/* Flush */ /* Flush */
readl(&instance->reg_set->doorbell); readl(&instance->reg_set->doorbell);
if (instance->mpio && instance->requestorId) if (instance->requestorId && instance->peerIsPresent)
memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
} else { } else {
writel(MFI_STOP_ADP, writel(MFI_STOP_ADP,
...@@ -5182,7 +5182,9 @@ static int megasas_init_fw(struct megasas_instance *instance) ...@@ -5182,7 +5182,9 @@ static int megasas_init_fw(struct megasas_instance *instance)
tmp_sectors = min_t(u32, max_sectors_1, max_sectors_2); tmp_sectors = min_t(u32, max_sectors_1, max_sectors_2);
instance->mpio = ctrl_info->adapterOperations2.mpio; instance->peerIsPresent = ctrl_info->cluster.peerIsPresent;
instance->passive = ctrl_info->cluster.passive;
memcpy(instance->clusterId, ctrl_info->clusterId, sizeof(instance->clusterId));
instance->UnevenSpanSupport = instance->UnevenSpanSupport =
ctrl_info->adapterOperations2.supportUnevenSpans; ctrl_info->adapterOperations2.supportUnevenSpans;
if (instance->UnevenSpanSupport) { if (instance->UnevenSpanSupport) {
......
...@@ -3325,27 +3325,37 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd) ...@@ -3325,27 +3325,37 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd)
return ret; return ret;
} }
/*SRIOV get other instance in cluster if any*/
struct megasas_instance *megasas_get_peer_instance(struct megasas_instance *instance)
{
int i;
for (i = 0; i < MAX_MGMT_ADAPTERS; i++) {
if (megasas_mgmt_info.instance[i] &&
(megasas_mgmt_info.instance[i] != instance) &&
megasas_mgmt_info.instance[i]->requestorId &&
megasas_mgmt_info.instance[i]->peerIsPresent &&
(memcmp((megasas_mgmt_info.instance[i]->clusterId),
instance->clusterId, MEGASAS_CLUSTER_ID_SIZE) == 0))
return megasas_mgmt_info.instance[i];
}
return NULL;
}
/* Check for a second path that is currently UP */ /* Check for a second path that is currently UP */
int megasas_check_mpio_paths(struct megasas_instance *instance, int megasas_check_mpio_paths(struct megasas_instance *instance,
struct scsi_cmnd *scmd) struct scsi_cmnd *scmd)
{ {
int i, j, retval = (DID_RESET << 16); struct megasas_instance *peer_instance = NULL;
int retval = (DID_RESET << 16);
if (instance->mpio && instance->requestorId) {
for (i = 0 ; i < MAX_MGMT_ADAPTERS ; i++) if (instance->peerIsPresent) {
for (j = 0 ; j < MAX_LOGICAL_DRIVES; j++) peer_instance = megasas_get_peer_instance(instance);
if (megasas_mgmt_info.instance[i] && if ((peer_instance) &&
(megasas_mgmt_info.instance[i] != instance) && (atomic_read(&peer_instance->adprecovery) ==
megasas_mgmt_info.instance[i]->mpio && MEGASAS_HBA_OPERATIONAL))
megasas_mgmt_info.instance[i]->requestorId retval = (DID_NO_CONNECT << 16);
&&
(megasas_mgmt_info.instance[i]->ld_ids[j]
== scmd->device->id)) {
retval = (DID_NO_CONNECT << 16);
goto out;
}
} }
out:
return retval; return retval;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment