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,