[PATCH 3/4] megaraid_sas: Fix LD/VF affiliation parsing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



James/linux-scsi,

The following patch for megaraid_sas fixes the LD/VF affiliation policy parsing code to account for LD targetId's and Hidden LD's (not yet affiliated with any Virtual Functions).

Signed-off-by: Adam Radford <aradford@xxxxxxxxx>
---
 drivers/scsi/megaraid/megaraid_sas.h      |  1 +
 drivers/scsi/megaraid/megaraid_sas_base.c | 88 ++++++++++++++++++++++---------
 2 files changed, 64 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 7d722fb..2e2fcb2 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1659,6 +1659,7 @@ struct MR_LD_VF_AFFILIATION {
 /* Plasma 1.11 FW backward compatibility structures */
 #define IOV_111_OFFSET 0x7CE
 #define MAX_VIRTUAL_FUNCTIONS 8
+#define MR_LD_ACCESS_HIDDEN 15
 
 struct IOV_111 {
 	u8 maxVFsSupported;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 112799b..8f62b30 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1836,7 +1836,7 @@ static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
 	struct MR_LD_VF_MAP *newmap = NULL, *savedmap = NULL;
 	dma_addr_t new_affiliation_h;
 	dma_addr_t new_affiliation_111_h;
-	int ld, retval = 0;
+	int ld, i, j, retval = 0, found = 0, doscan = 0;
 	u8 thisVf;
 
 	cmd = megasas_get_cmd(instance);
@@ -1944,14 +1944,6 @@ static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
 
 	if (!initial) {
 		if (instance->PlasmaFW111) {
-			if (!new_affiliation_111->vdCount) {
-				printk(KERN_WARNING "megasas: SR-IOV: Got new "
-				       "LD/VF affiliation for passive path "
-				       "for scsi%d.\n",
-					instance->host->host_no);
-				retval = 1;
-				goto out;
-			}
 			thisVf = new_affiliation_111->thisVf;
 			for (ld = 0 ; ld < new_affiliation_111->vdCount; ld++)
 				if (instance->vf_affiliation_111->map[ld].policy[thisVf] != new_affiliation_111->map[ld].policy[thisVf]) {
@@ -1977,29 +1969,75 @@ static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
 			newmap = new_affiliation->map;
 			savedmap = instance->vf_affiliation->map;
 			thisVf = new_affiliation->thisVf;
-			for (ld = 0 ; ld < new_affiliation->ldCount; ld++) {
-				if (savedmap->policy[thisVf] !=
-				    newmap->policy[thisVf]) {
-					printk(KERN_WARNING "megasas: SR-IOV: "
-					       "Got new LD/VF affiliation "
-					       "for scsi%d.\n",
-						instance->host->host_no);
-					memcpy(instance->vf_affiliation,
-					       new_affiliation,
-					       new_affiliation->size);
-					retval = 1;
+			for (i = 0 ; i < new_affiliation->ldCount; i++) {
+				found = 0;
+				for (j = 0;
+				     j < instance->vf_affiliation->ldCount;
+				     j++) {
+					if (newmap->ref.targetId ==
+					    savedmap->ref.targetId) {
+						found = 1;
+						if (newmap->policy[thisVf] !=
+						    savedmap->policy[thisVf]) {
+							doscan = 1;
+							goto out;
+						}
+					}
+					savedmap =
+					  (struct MR_LD_VF_MAP *)
+					  ((unsigned char *)savedmap +
+					   savedmap->size);
+				}
+				if (!found && newmap->policy[thisVf] !=
+				    MR_LD_ACCESS_HIDDEN) {
+					doscan = 1;
 					goto out;
 				}
-				savedmap = (struct MR_LD_VF_MAP *)
-					((unsigned char *)savedmap +
-					 savedmap->size);
 				newmap = (struct MR_LD_VF_MAP *)
-					((unsigned char *)newmap +
-					 newmap->size);
+				  ((unsigned char *)newmap + newmap->size);
+			}
+
+			newmap = new_affiliation->map;
+			savedmap = instance->vf_affiliation->map;
+
+			for (i = 0 ; i < instance->vf_affiliation->ldCount;
+			     i++) {
+				found = 0;
+				for (j = 0 ; j < new_affiliation->ldCount;
+				     j++) {
+					if (savedmap->ref.targetId ==
+					    newmap->ref.targetId) {
+						found = 1;
+						if (savedmap->policy[thisVf] !=
+						    newmap->policy[thisVf]) {
+							doscan = 1;
+							goto out;
+						}
+					}
+					newmap = (struct MR_LD_VF_MAP *)
+					  ((unsigned char *)newmap +
+					   newmap->size);
+				}
+				if (!found && savedmap->policy[thisVf] !=
+				    MR_LD_ACCESS_HIDDEN) {
+					doscan = 1;
+					goto out;
+				}
+				savedmap = (struct MR_LD_VF_MAP *)
+				  ((unsigned char *)savedmap +
+				   savedmap->size);
 			}
 		}
 	}
 out:
+	if (doscan) {
+		printk(KERN_WARNING "megasas: SR-IOV: Got new LD/VF "
+		       "affiliation for scsi%d.\n", instance->host->host_no);
+		memcpy(instance->vf_affiliation, new_affiliation,
+		       new_affiliation->size);
+		retval = 1;
+	}
+
 	if (new_affiliation) {
 		if (instance->PlasmaFW111)
 			pci_free_consistent(instance->pdev,
-- 
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux