summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubhash Jadavani <subhashj@codeaurora.org>2015-10-05 16:22:38 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:00:42 -0700
commitbe361c995c1af8e6766cbc27a46c32489d2f0116 (patch)
tree8d3a967a9e6045a876ff5a580071c87357c20e9d
parenta2f12c798729973c286a7af79f24be09f87e7d7f (diff)
scsi: ufs: allow updating bBootLunEn via ioctl
"bBootLunEn" attribute value decides the active Boot LUN but there could be a case where userspace may want to change it during image update. This change allows writing to this parameter. Change-Id: I6e8d630606d8caf6197ef662003ec1ee646afe81 Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
-rw-r--r--drivers/scsi/ufs/ufshcd.c35
-rw-r--r--include/uapi/scsi/ufs/ioctl.h4
-rw-r--r--include/uapi/scsi/ufs/ufs.h2
3 files changed, 38 insertions, 3 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 024d913cf248..eeed0e858290 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -6777,6 +6777,37 @@ static int ufshcd_query_ioctl(struct ufs_hba *hba, u8 lun, void __user *buffer)
err = ufshcd_query_attr(hba, ioctl_data->opcode, ioctl_data->idn,
index, 0, &att);
break;
+
+ case UPIU_QUERY_OPCODE_WRITE_ATTR:
+ err = copy_from_user(&att,
+ buffer + sizeof(struct ufs_ioctl_query_data),
+ sizeof(u32));
+ if (err) {
+ dev_err(hba->dev,
+ "%s: Failed copying buffer from user, err %d\n",
+ __func__, err);
+ goto out_release_mem;
+ }
+
+ switch (ioctl_data->idn) {
+ case QUERY_ATTR_IDN_BOOT_LU_EN:
+ index = 0;
+ if (att > QUERY_ATTR_IDN_BOOT_LU_EN_MAX) {
+ dev_err(hba->dev,
+ "%s: Illegal ufs query ioctl data, opcode 0x%x, idn 0x%x, att 0x%x\n",
+ __func__, ioctl_data->opcode,
+ (unsigned int)ioctl_data->idn, att);
+ err = -EINVAL;
+ goto out_release_mem;
+ }
+ break;
+ default:
+ goto out_einval;
+ }
+ err = ufshcd_query_attr(hba, ioctl_data->opcode,
+ ioctl_data->idn, index, 0, &att);
+ break;
+
case UPIU_QUERY_OPCODE_READ_FLAG:
switch (ioctl_data->idn) {
case QUERY_FLAG_IDN_FDEVICEINIT:
@@ -6822,8 +6853,10 @@ static int ufshcd_query_ioctl(struct ufs_hba *hba, u8 lun, void __user *buffer)
ioctl_data->buf_size = 1;
data_ptr = &flag;
break;
+ case UPIU_QUERY_OPCODE_WRITE_ATTR:
+ goto out_release_mem;
default:
- BUG_ON(true);
+ goto out_einval;
}
/* copy to user */
diff --git a/include/uapi/scsi/ufs/ioctl.h b/include/uapi/scsi/ufs/ioctl.h
index f7a671873b40..56b2f4616aa4 100644
--- a/include/uapi/scsi/ufs/ioctl.h
+++ b/include/uapi/scsi/ufs/ioctl.h
@@ -48,8 +48,8 @@ struct ufs_ioctl_query_data {
* placeholder for the start of the data buffer where kernel will copy
* the query data (attribute/flag/descriptor) read from the UFS device
* Note:
- * For Read Attribute you will have to allocate 4 bytes
- * For Read Flag you will have to allocate 1 byte
+ * For Read/Write Attribute you will have to allocate 4 bytes
+ * For Read/Write Flag you will have to allocate 1 byte
*/
__u8 buffer[0];
};
diff --git a/include/uapi/scsi/ufs/ufs.h b/include/uapi/scsi/ufs/ufs.h
index 4b9a0049639d..cd82b760bd92 100644
--- a/include/uapi/scsi/ufs/ufs.h
+++ b/include/uapi/scsi/ufs/ufs.h
@@ -38,6 +38,8 @@ enum attr_idn {
QUERY_ATTR_IDN_CORR_PRG_BLK_NUM = 0x11,
};
+#define QUERY_ATTR_IDN_BOOT_LU_EN_MAX 0x02
+
/* Descriptor idn for Query requests */
enum desc_idn {
QUERY_DESC_IDN_DEVICE = 0x0,