[PATCH V2 08/13] pm80xx : IOCTL functionality to get phy error.

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

 



From: Viswas G <Viswas.G@xxxxxxxxxxxxx>

Added the IOCTL functionality for phy error so that management utility
can get the information like Invalid dword count, Disparity error count,
Loss of sync dword count, phy reset count from driver using get phy
profile command.

Signed-off-by: Deepak Ukey <deepak.ukey@xxxxxxxxxxxxx>
Signed-off-by: Viswas G <Viswas.G@xxxxxxxxxxxxx>
Signed-off-by: Radha Ramachandran <radha@xxxxxxxxxx>
---
 drivers/scsi/pm8001/pm8001_ctl.c | 54 ++++++++++++++++++++++++++++++++++++++++
 drivers/scsi/pm8001/pm8001_ctl.h | 12 +++++++++
 drivers/scsi/pm8001/pm80xx_hwi.c | 14 +++++++++++
 drivers/scsi/pm8001/pm80xx_hwi.h |  1 +
 4 files changed, 81 insertions(+)

diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index eb64566b2274..7f45e114a31a 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -1026,6 +1026,57 @@ static int pm8001_ioctl_get_phy_profile(struct pm8001_hba_info *pm8001_ha,
 	return ret;
 }
 
+static int pm8001_ioctl_get_phy_err(struct pm8001_hba_info *pm8001_ha,
+		unsigned long arg)
+{
+	struct phy_errcnt phy_err[MAX_NUM_PHYS];
+	DECLARE_COMPLETION_ONSTACK(completion);
+	unsigned long timeout = msecs_to_jiffies(2000);
+	u32 ret = 0, i;
+	int page_code = SAS_PHY_ERR_COUNTERS_PAGE;
+	/*6H card does not support phyerr*/
+	if (pm8001_ha->pdev->device == 0x8001 ||
+			pm8001_ha->pdev->device == 0x8081) {
+		return ADPT_IOCTL_CALL_INVALID_DEVICE;
+	}
+
+	mutex_lock(&pm8001_ha->ioctl_mutex);
+
+	for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
+		pm8001_ha->ioctl_completion = &completion;
+		ret = PM8001_CHIP_DISP->get_phy_profile_req(pm8001_ha,
+				i, page_code);
+		if (ret != 0) {
+			PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+				"Get phy profile request failed\n"));
+			ret = ADPT_IOCTL_CALL_FAILED;
+			goto exit;
+		}
+		timeout = wait_for_completion_timeout(&completion,
+				timeout);
+		if (timeout == 0) {
+			ret = ADPT_IOCTL_CALL_FAILED;
+			goto exit;
+		}
+		memcpy((void *)&phy_err[i],
+			(void *)&pm8001_ha->phy_profile_resp,
+			sizeof(struct phy_errcnt));
+	}
+
+	if (copy_to_user((void *)arg, (void *)&phy_err,
+				sizeof(struct phy_errcnt) * (i))) {
+		PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("copy_to_user failed\n"));
+		ret = ADPT_IOCTL_CALL_FAILED;
+	}
+exit:
+	spin_lock_irq(&pm8001_ha->ioctl_lock);
+	pm8001_ha->ioctl_completion = NULL;
+	spin_unlock_irq(&pm8001_ha->ioctl_lock);
+	mutex_unlock(&pm8001_ha->ioctl_mutex);
+	return ret;
+}
+
 /**
  *	pm8001_ioctl - pm8001 configuration request
  *	@inode: inode of device
@@ -1052,6 +1103,9 @@ static long pm8001_ioctl(struct file *file,
 	case ADPT_IOCTL_GET_PHY_PROFILE:
 		ret = pm8001_ioctl_get_phy_profile(pm8001_ha, arg);
 		return ret;
+	case ADPT_IOCTL_GET_PHY_ERR_CNT:
+		ret = pm8001_ioctl_get_phy_err(pm8001_ha, arg);
+		break;
 	default:
 		ret = ADPT_IOCTL_CALL_INVALID_CODE;
 	}
diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h
index 226fab82845f..686ad69f0e0c 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.h
+++ b/drivers/scsi/pm8001/pm8001_ctl.h
@@ -102,15 +102,27 @@ struct phy_profile {
 	unsigned int	reserved2:20;
 } __packed;
 
+struct phy_errcnt {
+	unsigned int  InvalidDword;
+	unsigned int  runningDisparityError;
+	unsigned int  codeViolation;
+	unsigned int  LossOfSyncDW;
+	unsigned int  phyResetProblem;
+	unsigned int  inboundCRCError;
+};
+
 struct phy_prof_resp {
 	union {
 		struct phy_profile status;
+		struct phy_errcnt errcnt;
 	} phy;
 };
 
 #define ADPT_IOCTL_INFO _IOR(ADPT_MAGIC_NUMBER, 0, struct ioctl_info_buffer *)
 #define ADPT_IOCTL_GET_PHY_PROFILE _IOWR(ADPT_MAGIC_NUMBER, 8, \
 		struct phy_profile*)
+#define ADPT_IOCTL_GET_PHY_ERR_CNT _IOWR(ADPT_MAGIC_NUMBER, 9, \
+		struct phy_err*)
 #define ADPT_MAGIC_NUMBER	'm'
 
 #endif /* PM8001_CTL_H_INCLUDED */
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 0a36c5d5e2c2..e8af262976d6 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -3690,6 +3690,7 @@ static int mpi_get_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
 {
 	u32 tag, page_code;
 	struct phy_profile *phy_profile, *phy_prof;
+	struct phy_errcnt *phy_err, *phy_err_cnt;
 	struct get_phy_profile_resp *pPayload =
 		(struct get_phy_profile_resp *)(piomb + 4);
 	u32 status = le32_to_cpu(pPayload->status);
@@ -3725,6 +3726,19 @@ static int mpi_get_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
 			phy_profile->nlr = le32_to_cpu(phy_prof->nlr);
 			phy_profile->port_id = le32_to_cpu(phy_prof->port_id);
 			phy_profile->prts = le32_to_cpu(phy_prof->prts);
+		} else if (page_code == SAS_PHY_ERR_COUNTERS_PAGE) {
+			phy_err =
+			(struct phy_errcnt *)&pm8001_ha->phy_profile_resp;
+			phy_err_cnt =
+			(struct phy_errcnt *)pPayload->ppc_specific_rsp;
+			phy_err->InvalidDword =
+			le32_to_cpu(phy_err_cnt->InvalidDword);
+			phy_err->runningDisparityError =
+			le32_to_cpu(phy_err_cnt->runningDisparityError);
+			phy_err->LossOfSyncDW =
+			le32_to_cpu(phy_err_cnt->LossOfSyncDW);
+			phy_err->phyResetProblem =
+			le32_to_cpu(phy_err_cnt->phyResetProblem);
 		}
 		complete(pm8001_ha->ioctl_completion);
 	}
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index 230877caeed4..b5119c5479da 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -175,6 +175,7 @@
 #define PHY_STOP_ERR_DEVICE_ATTACHED	0x1046
 
 /* phy_profile */
+#define SAS_PHY_ERR_COUNTERS_PAGE	0x01
 #define SAS_PHY_ANALOG_SETTINGS_PAGE	0x04
 #define SAS_PHY_GENERAL_STATUS_PAGE	0x05
 #define PHY_DWORD_LENGTH		0xC
-- 
2.16.3




[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