diff mbox series

[6/6] scsi: ufs-bsg: Add support for uic commands in ufs_bsg_request()

Message ID 1533110672-12785-7-git-send-email-avri.altman@wdc.com (mailing list archive)
State Changes Requested
Headers show
Series scsi: scsi transport for ufs devices | expand

Commit Message

Avri Altman Aug. 1, 2018, 8:04 a.m. UTC
Add support to those uic commands, that are currently supported
by ufshcd api: the variants of dme_{peer}_{set_get}.

At this point better not to add any new api, as careless
uic command may turn the device into a brick.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/scsi/ufs/ufs_bsg.c | 56 +++++++++++++++++++++++++++++++++++++++++++++-
 drivers/scsi/ufs/ufs_bsg.h |  1 +
 2 files changed, 56 insertions(+), 1 deletion(-)

Comments

Bart Van Assche Aug. 1, 2018, 3:38 p.m. UTC | #1
On Wed, 2018-08-01 at 11:04 +0300, Avri Altman wrote:
> +	struct uic_command uc = {0};

Please use "{ }" or "{}" for structure initialization as is done elsewhere in
the kernel instead of "{0}".

> +#define UIC_CMD_SIZE (sizeof(u32) * 4)

Please add a comment above this definition that explains whether this constant
comes from the spec or whether it has another origin.

Thanks,

Bart.
Avri Altman Aug. 2, 2018, 3:18 p.m. UTC | #2
Thanks,
Avri

> -----Original Message-----
> From: Bart Van Assche
> Sent: Wednesday, August 01, 2018 6:39 PM
> To: hch@lst.de; Avri Altman ; linux-scsi@vger.kernel.org;
> jthumshirn@suse.de; hare@suse.com; martin.petersen@oracle.com;
> jejb@linux.vnet.ibm.com
> Cc: Vinayak Holikatti ; Avi Shchislowski ; Alex Lemberg ; Stanislav Nijnikov ;
> subhashj@codeaurora.org
> Subject: Re: [PATCH 6/6] scsi: ufs-bsg: Add support for uic commands in
> ufs_bsg_request()
> 
> On Wed, 2018-08-01 at 11:04 +0300, Avri Altman wrote:
> > +	struct uic_command uc = {0};
> 
> Please use "{ }" or "{}" for structure initialization as is done elsewhere in
> the kernel instead of "{0}".
Done.

> 
> > +#define UIC_CMD_SIZE (sizeof(u32) * 4)
> 
> Please add a comment above this definition that explains whether this
> constant
> comes from the spec or whether it has another origin.
Done.

> 
> Thanks,
> 
> Bart.
diff mbox series

Patch

diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c
index d077e42..441d096 100644
--- a/drivers/scsi/ufs/ufs_bsg.c
+++ b/drivers/scsi/ufs/ufs_bsg.c
@@ -63,6 +63,55 @@  static int ufs_bsg_verify_query_size(unsigned int request_len,
 	return 0;
 }
 
+static int ufs_bsg_exec_uic_cmd(struct uic_command *uc)
+{
+	u32 attr_sel = uc->argument1;
+	u8 attr_set = (uc->argument2 >> 16) & 0xff;
+	u32 mib_val = uc->argument3;
+	int cmd = uc->command;
+	int ret = 0;
+
+	switch (cmd) {
+	case UIC_CMD_DME_GET:
+		ret = ufshcd_dme_get_attr(bsg_host->hba, attr_sel,
+					  &mib_val, DME_LOCAL);
+		break;
+	case UIC_CMD_DME_SET:
+		ret = ufshcd_dme_set_attr(bsg_host->hba, attr_sel, attr_set,
+					  mib_val, DME_LOCAL);
+		break;
+	case UIC_CMD_DME_PEER_GET:
+		ret = ufshcd_dme_get_attr(bsg_host->hba, attr_sel,
+					  &mib_val, DME_PEER);
+		break;
+	case UIC_CMD_DME_PEER_SET:
+		ret = ufshcd_dme_set_attr(bsg_host->hba, attr_sel, attr_set,
+					  mib_val, DME_PEER);
+		break;
+	case UIC_CMD_DME_POWERON:
+	case UIC_CMD_DME_POWEROFF:
+	case UIC_CMD_DME_ENABLE:
+	case UIC_CMD_DME_RESET:
+	case UIC_CMD_DME_END_PT_RST:
+	case UIC_CMD_DME_LINK_STARTUP:
+	case UIC_CMD_DME_HIBER_ENTER:
+	case UIC_CMD_DME_HIBER_EXIT:
+	case UIC_CMD_DME_TEST_MODE:
+		ret = -ENOTSUPP;
+		pr_err("%s unsupported command 0x%x\n", __func__, cmd);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	if (ret)
+		pr_err("%s error in command 0x%x\n", __func__, cmd);
+
+	uc->argument3 = mib_val;
+
+	return ret;
+}
+
 static int ufs_bsg_request(struct bsg_job *job)
 {
 	struct ufs_bsg_request *bsg_request = job->request;
@@ -70,6 +119,7 @@  static int ufs_bsg_request(struct bsg_job *job)
 	unsigned int request_len = job->request_len;
 	unsigned int reply_len = job->reply_len;
 	struct utp_upiu_query *qr;
+	struct uic_command uc = {0};
 	__be32 *req_upiu = NULL;
 	__be32 *rsp_upiu = NULL;
 	int msgcode;
@@ -124,7 +174,11 @@  static int ufs_bsg_request(struct bsg_job *job)
 
 		break;
 	case UPIU_TRANSACTION_UIC_CMD:
-		/* later */
+		memcpy(&uc, &bsg_request->tsf.uc, UIC_CMD_SIZE);
+		ret = ufs_bsg_exec_uic_cmd(&uc);
+		memcpy(&bsg_reply->tsf.uc, &uc, UIC_CMD_SIZE);
+
+		break;
 	case UPIU_TRANSACTION_COMMAND:
 	case UPIU_TRANSACTION_DATA_OUT:
 not_supported:
diff --git a/drivers/scsi/ufs/ufs_bsg.h b/drivers/scsi/ufs/ufs_bsg.h
index 0fd2859..651ffb3 100644
--- a/drivers/scsi/ufs/ufs_bsg.h
+++ b/drivers/scsi/ufs/ufs_bsg.h
@@ -15,6 +15,7 @@ 
 
 #define UFS_BSG_NOP (-1)
 #define UPIU_TRANSACTION_UIC_CMD 0x1F
+#define UIC_CMD_SIZE (sizeof(u32) * 4)
 
 enum {
 	REQ_UPIU_SIZE_DWORDS	= 8,