From: Deepak Ukey <deepak.ukey@microchip.com>
To: <linux-scsi@vger.kernel.org>
Cc: <Vasanthalakshmi.Tharmarajan@microchip.com>,
<Viswas.G@microchip.com>, <deepak.ukey@microchip.com>,
<jinpu.wang@profitbricks.com>, <martin.petersen@oracle.com>,
<yuuzheng@google.com>, <auradkar@google.com>,
<vishakhavc@google.com>, <bjashnani@google.com>,
<radha@google.com>, <akshatzen@google.com>
Subject: [PATCH V2 07/13] pm80xx : IOCTL functionality to get phy status.
Date: Fri, 17 Jan 2020 12:49:17 +0530 [thread overview]
Message-ID: <20200117071923.7445-8-deepak.ukey@microchip.com> (raw)
In-Reply-To: <20200117071923.7445-1-deepak.ukey@microchip.com>
From: Viswas G <Viswas.G@microchip.com>
Added the IOCTL functionality for phy status so that management
utility can get the information like phy id, phy status, port id
and port status from driver using get phy profile command.
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
---
drivers/scsi/pm8001/pm8001_ctl.c | 90 ++++++++++++++++++++++++++++++++++++++++
drivers/scsi/pm8001/pm8001_ctl.h | 23 +++++++++-
drivers/scsi/pm8001/pm8001_sas.h | 7 ++++
drivers/scsi/pm8001/pm80xx_hwi.c | 68 ++++++++++++++++++++++++++++++
drivers/scsi/pm8001/pm80xx_hwi.h | 1 +
5 files changed, 188 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 8091e78a04b0..eb64566b2274 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -41,6 +41,8 @@
#include <linux/slab.h>
#include "pm8001_sas.h"
#include "pm8001_ctl.h"
+#include "pm80xx_hwi.h"
+
int pm80xx_major = -1;
/* scsi host attributes */
@@ -939,6 +941,91 @@ static long pm8001_info_ioctl(struct pm8001_hba_info *pm8001_ha,
return ret;
}
+static int pm8001_ioctl_get_phy_profile(struct pm8001_hba_info *pm8001_ha,
+ unsigned long arg)
+{
+ struct phy_profile phy_prof[MAX_NUM_PHYS];
+ int nphys;
+ DECLARE_COMPLETION_ONSTACK(completion);
+ unsigned long timeout = msecs_to_jiffies(2000);
+ u32 ret = 0, i;
+ int page_code = SAS_PHY_GENERAL_STATUS_PAGE;
+
+ if (pm8001_ha->pdev->device == 0x8001 ||
+ pm8001_ha->pdev->device == 0x8081) {
+ return ADPT_IOCTL_CALL_INVALID_DEVICE;
+ }
+
+ if (copy_from_user(&phy_prof[0], (struct phy_profile *)arg,
+ sizeof(struct phy_profile))) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("copy_from_user failed\n"));
+ return ADPT_IOCTL_CALL_FAILED;
+ }
+
+ mutex_lock(&pm8001_ha->ioctl_mutex);
+ nphys = phy_prof[0].phy_id;
+ if (nphys == -1) {
+ 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_prof[i],
+ (void *)&pm8001_ha->phy_profile_resp,
+ sizeof(struct phy_profile));
+ }
+
+ if (copy_to_user((void *)arg, (void *)&phy_prof,
+ sizeof(struct phy_profile) * (i))) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("copy_to_user failed\n"));
+ ret = ADPT_IOCTL_CALL_FAILED;
+ }
+ } else {
+ pm8001_ha->ioctl_completion = &completion;
+ ret = PM8001_CHIP_DISP->get_phy_profile_req(pm8001_ha,
+ nphys, 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;
+ }
+
+ if (copy_to_user((void *)arg,
+ (void *)&pm8001_ha->phy_profile_resp,
+ sizeof(struct phy_profile))) {
+ 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
@@ -962,6 +1049,9 @@ static long pm8001_ioctl(struct file *file,
case ADPT_IOCTL_INFO:
ret = pm8001_info_ioctl(pm8001_ha, arg);
break;
+ case ADPT_IOCTL_GET_PHY_PROFILE:
+ ret = pm8001_ioctl_get_phy_profile(pm8001_ha, arg);
+ return ret;
default:
ret = ADPT_IOCTL_CALL_INVALID_CODE;
}
diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h
index f0f8b1deae27..226fab82845f 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.h
+++ b/drivers/scsi/pm8001/pm8001_ctl.h
@@ -63,6 +63,9 @@
#define ADPT_IOCTL_CALL_SUCCESS 0x00
#define ADPT_IOCTL_CALL_FAILED 0x01
#define ADPT_IOCTL_CALL_INVALID_CODE 0x03
+#define ADPT_IOCTL_CALL_INVALID_DEVICE 0x04
+
+#define MAX_NUM_PHYS 16
struct ioctl_header {
u32 io_controller_num;
@@ -88,8 +91,26 @@ struct ioctl_info_buffer {
struct ioctl_drv_info information;
};
-#define ADPT_IOCTL_INFO _IOR(ADPT_MAGIC_NUMBER, 0, struct ioctl_info_buffer *)
+struct phy_profile {
+ char phy_id;
+ unsigned int phys:4;
+ unsigned int nlr:4;
+ unsigned int plr:4;
+ unsigned int reserved1:12;
+ unsigned char port_id;
+ unsigned int prts:4;
+ unsigned int reserved2:20;
+} __packed;
+struct phy_prof_resp {
+ union {
+ struct phy_profile status;
+ } 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_MAGIC_NUMBER 'm'
#endif /* PM8001_CTL_H_INCLUDED */
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 479aac34d7cc..87d676810a18 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -56,6 +56,7 @@
#include <scsi/sas_ata.h>
#include <linux/atomic.h>
#include "pm8001_defs.h"
+#include "pm8001_ctl.h"
#define DRV_NAME "pm80xx"
#define DRV_VERSION "0.1.39"
@@ -246,6 +247,8 @@ struct pm8001_dispatch {
int (*sas_diag_execute_req)(struct pm8001_hba_info *pm8001_ha,
u32 state);
int (*sas_re_init_req)(struct pm8001_hba_info *pm8001_ha);
+ int (*get_phy_profile_req)(struct pm8001_hba_info *pm8001_ha,
+ int phy, int page);
};
struct pm8001_chip_info {
@@ -560,6 +563,10 @@ struct pm8001_hba_info {
bool controller_fatal_error;
const struct firmware *fw_image;
struct isr_param irq_vector[PM8001_MAX_MSIX_VEC];
+ spinlock_t ioctl_lock;
+ struct mutex ioctl_mutex;
+ struct completion *ioctl_completion;
+ struct phy_prof_resp phy_profile_resp;
u32 reset_in_progress;
};
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 37b82d7aa3d7..0a36c5d5e2c2 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -3688,9 +3688,48 @@ static int mpi_get_controller_config_resp(struct pm8001_hba_info *pm8001_ha,
static int mpi_get_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
void *piomb)
{
+ u32 tag, page_code;
+ struct phy_profile *phy_profile, *phy_prof;
+ struct get_phy_profile_resp *pPayload =
+ (struct get_phy_profile_resp *)(piomb + 4);
+ u32 status = le32_to_cpu(pPayload->status);
+
+ page_code = (u8)((pPayload->ppc_phyid & 0xFF00) >> 8);
+
PM8001_MSG_DBG(pm8001_ha,
pm8001_printk(" pm80xx_addition_functionality\n"));
+ if (status) {
+ /* status is FAILED */
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+ "mpiGetPhyProfileReq failed with status 0x%08x\n",
+ status));
+ }
+
+ tag = le32_to_cpu(pPayload->tag);
+
+ spin_lock(&pm8001_ha->ioctl_lock);
+ if (pm8001_ha->ioctl_completion != NULL) {
+ if (status) {
+ /* signal fail status */
+ memset(&pm8001_ha->phy_profile_resp, 0xff,
+ sizeof(pm8001_ha->phy_profile_resp));
+ } else if (page_code == SAS_PHY_GENERAL_STATUS_PAGE) {
+ phy_profile =
+ (struct phy_profile *)&pm8001_ha->phy_profile_resp;
+ phy_prof =
+ (struct phy_profile *)pPayload->ppc_specific_rsp;
+ phy_profile->phy_id = le32_to_cpu(phy_prof->phy_id);
+ phy_profile->phys = le32_to_cpu(phy_prof->phys);
+ phy_profile->plr = le32_to_cpu(phy_prof->plr);
+ 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);
+ }
+ complete(pm8001_ha->ioctl_completion);
+ }
+ spin_unlock(&pm8001_ha->ioctl_lock);
+ pm8001_tag_free(pm8001_ha, tag);
return 0;
}
@@ -4883,6 +4922,34 @@ pm80xx_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec)
return IRQ_HANDLED;
}
+int pm8001_chip_get_phy_profile(struct pm8001_hba_info *pm8001_ha,
+ int phy_id, int page_code)
+{
+
+ u32 tag;
+ struct get_phy_profile_req payload;
+ struct inbound_queue_table *circularQ;
+ int rc, ppc_phyid;
+ u32 opc = OPC_INB_GET_PHY_PROFILE;
+
+ memset(&payload, 0, sizeof(payload));
+
+ rc = pm8001_tag_alloc(pm8001_ha, &tag);
+ if (rc)
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Invalid tag\n"));
+
+ circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
+ payload.tag = cpu_to_le32(tag);
+ ppc_phyid = (page_code & 0xFF) << 8 | (phy_id & 0xFF);
+ payload.ppc_phyid = cpu_to_le32(ppc_phyid);
+
+ pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+ sizeof(payload), 0);
+
+ return rc;
+}
+
void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
u32 operation, u32 phyid, u32 length, u32 *buf)
{
@@ -4983,4 +5050,5 @@ const struct pm8001_dispatch pm8001_80xx_dispatch = {
.set_nvmd_req = pm8001_chip_set_nvmd_req,
.fw_flash_update_req = pm8001_chip_fw_flash_update_req,
.set_dev_state_req = pm8001_chip_set_dev_state_req,
+ .get_phy_profile_req = pm8001_chip_get_phy_profile,
};
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index 701951a0f715..230877caeed4 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -176,6 +176,7 @@
/* phy_profile */
#define SAS_PHY_ANALOG_SETTINGS_PAGE 0x04
+#define SAS_PHY_GENERAL_STATUS_PAGE 0x05
#define PHY_DWORD_LENGTH 0xC
/* Thermal related */
--
2.16.3
next prev parent reply other threads:[~2020-01-17 7:10 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 01/13] pm80xx : Increase request sg length Deepak Ukey
2020-01-17 14:08 ` Jinpu Wang
2020-01-17 15:50 ` Deepak.Ukey
2020-01-17 15:53 ` Jinpu Wang
2020-01-20 4:20 ` Deepak.Ukey
2020-01-20 8:47 ` Jinpu Wang
2020-01-29 9:02 ` Deepak.Ukey
2020-01-17 7:19 ` [PATCH V2 02/13] pm80xx : Deal with kexec reboots Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 03/13] pm80xx : Free the tag when mpi_set_phy_profile_resp is received Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 04/13] pm80xx : Cleanup initialization loading fail path Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 05/13] pm80xx : Support for char device Deepak Ukey
2020-01-17 14:15 ` Jinpu Wang
2020-01-21 0:24 ` Martin K. Petersen
2020-01-21 5:33 ` Deepak.Ukey
2020-01-21 12:39 ` John Garry
2020-01-22 8:50 ` Deepak.Ukey
2020-01-22 12:38 ` John Garry
2020-01-28 9:43 ` Deepak.Ukey
2020-03-11 17:08 ` Jinpu Wang
2020-03-11 22:13 ` Douglas Gilbert
2020-03-12 8:49 ` Jinpu Wang
2020-03-12 10:58 ` John Garry
2020-03-16 6:22 ` Deepak.Ukey
2020-01-17 7:19 ` [PATCH V2 06/13] pm80xx : sysfs attribute for number of phys Deepak Ukey
2020-01-17 14:21 ` Jinpu Wang
2020-01-20 4:50 ` Deepak.Ukey
2020-01-21 7:55 ` Jinpu Wang
2020-01-17 7:19 ` Deepak Ukey [this message]
2020-01-17 14:35 ` [PATCH V2 07/13] pm80xx : IOCTL functionality to get phy status Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 08/13] pm80xx : IOCTL functionality to get phy error Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 09/13] pm80xx : IOCTL functionality for GPIO Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 10/13] pm80xx : IOCTL functionality for SGPIO Deepak Ukey
2020-01-22 8:59 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 11/13] pm80xx : sysfs attribute for non fatal dump Deepak Ukey
2020-01-17 14:26 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 12/13] pm80xx : Introduce read and write length for IOCTL payload structure Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 13/13] pm80xx : IOCTL functionality for TWI device Deepak Ukey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200117071923.7445-8-deepak.ukey@microchip.com \
--to=deepak.ukey@microchip.com \
--cc=Vasanthalakshmi.Tharmarajan@microchip.com \
--cc=Viswas.G@microchip.com \
--cc=akshatzen@google.com \
--cc=auradkar@google.com \
--cc=bjashnani@google.com \
--cc=jinpu.wang@profitbricks.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=radha@google.com \
--cc=vishakhavc@google.com \
--cc=yuuzheng@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox