Hi, > Expands sysfs boot_lun attribute to be writable. Necessary to enable > proper support for LUN switching on some UFS devices. Can you please elaborate why is it necessary? What use case are you running? > > Signed-off-by: Nia Espera <a5b6@xxxxxxxxxx> > --- > drivers/scsi/ufs/ufs-sysfs.c | 67 +++++++++++++++++++++++++++++++++++- > 1 file changed, 66 insertions(+), 1 deletion(-) > > diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c > index 5c405ff7b6ea..7bf5d6c3d0ec 100644 > --- a/drivers/scsi/ufs/ufs-sysfs.c > +++ b/drivers/scsi/ufs/ufs-sysfs.c > @@ -1047,6 +1047,71 @@ static inline bool ufshcd_is_wb_attrs(enum attr_idn > idn) > idn <= QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE; > } > > +static ssize_t boot_lun_enabled_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct ufs_hba *hba = dev_get_drvdata(dev); > + u32 slot; > + int ret; > + u8 index = 0; > + > + down(&hba->host_sem); > + if (!ufshcd_is_user_access_allowed(hba)) { > + up(&hba->host_sem); > + return -EBUSY; > + } > + if (ufshcd_is_wb_attrs(QUERY_ATTR_IDN_BOOT_LU_EN)) Clearly bBootLunEn is not a WB attribute. > + index = ufshcd_wb_get_query_index(hba); > + ufshcd_rpm_get_sync(hba); > + > + ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, > + QUERY_ATTR_IDN_BOOT_LU_EN, index, 0, &slot); > + > + ufshcd_rpm_put_sync(hba); > + if (ret) { > + ret = -EINVAL; > + goto out; > + } > + > + ret = sysfs_emit(buf, "0x%08X\n", slot); > +out: > + up(&hba->host_sem); > + return ret; > +} > + > +static ssize_t boot_lun_enabled_store(struct device *dev, > + struct device_attribute *attr, > + const char *buf, size_t count) > +{ > + struct ufs_hba *hba = dev_get_drvdata(dev); > + u32 slot; > + int ret; > + u8 index = 0; > + > + if (kstrtouint(buf, 0, &slot) < 0) > + return -EINVAL; You need to verify that no one set bBootLunEn = 0x0 because the device won't boot. Better check explicitly that slot != bBootLunEn and its either 1 or 2. Thanks, Avri > + > + down(&hba->host_sem); > + if (!ufshcd_is_user_access_allowed(hba)) { > + up(&hba->host_sem); > + return -EBUSY; > + } > + if (ufshcd_is_wb_attrs(QUERY_ATTR_IDN_BOOT_LU_EN)) > + index = ufshcd_wb_get_query_index(hba); > + ufshcd_rpm_get_sync(hba); > + > + ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, > + QUERY_ATTR_IDN_BOOT_LU_EN, index, 0, &slot); > + ufshcd_rpm_put_sync(hba); > + if (ret) { > + ret = -EINVAL; > + goto out; > + } > +out: > + up(&hba->host_sem); > + return ret ? ret : count; > +} > + > #define UFS_ATTRIBUTE(_name, _uname) \ > static ssize_t _name##_show(struct device *dev, \ > struct device_attribute *attr, char *buf) \ > @@ -1077,8 +1142,8 @@ out: \ > return ret; \ > } \ > static DEVICE_ATTR_RO(_name) > +static DEVICE_ATTR_RW(boot_lun_enabled); > > -UFS_ATTRIBUTE(boot_lun_enabled, _BOOT_LU_EN); > UFS_ATTRIBUTE(max_data_size_hpb_single_cmd, _MAX_HPB_SINGLE_CMD); > UFS_ATTRIBUTE(current_power_mode, _POWER_MODE); > UFS_ATTRIBUTE(active_icc_level, _ACTIVE_ICC_LVL); > -- > 2.36.1