Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70a77709 authored by Kyle Yan's avatar Kyle Yan Committed by Gerrit - the friendly Code Review server
Browse files

Merge "scsi: ufs: don't try adding boot and rpmb lun if not supported" into msm-4.8

parents 912e874c 2df121a6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -494,6 +494,14 @@ struct ufs_vreg_info {
	struct ufs_vreg *vdd_hba;
};

/* Possible values for bDeviceSubClass of device descriptor */
enum {
	UFS_DEV_EMBEDDED_BOOTABLE	= 0x00,
	UFS_DEV_EMBEDDED_NON_BOOTABLE	= 0x01,
	UFS_DEV_REMOVABLE_BOOTABLE	= 0x02,
	UFS_DEV_REMOVABLE_NON_BOOTABLE	= 0x03,
};

struct ufs_dev_info {
	/* device descriptor info */
	u8	b_device_sub_class;
+48 −19
Original line number Diff line number Diff line
@@ -6571,12 +6571,16 @@ static void ufshcd_set_active_icc_lvl(struct ufs_hba *hba)
 * ufshcd_scsi_add_wlus - Adds required W-LUs
 * @hba: per-adapter instance
 *
 * UFS device specification requires the UFS devices to support 4 well known
 * logical units:
 * UFS devices can support upto 4 well known logical units:
 *	"REPORT_LUNS" (address: 01h)
 *	"UFS Device" (address: 50h)
 *	"RPMB" (address: 44h)
 *	"BOOT" (address: 30h)
 *
 * "REPORT_LUNS" & "UFS Device" are mandatory for all device classes (see
 * "bDeviceSubClass" parameter of device descriptor) while "BOOT" is supported
 * only for bootable devices. "RPMB" is only supported with embedded devices.
 *
 * UFS device's power management needs to be controlled by "POWER CONDITION"
 * field of SSU (START STOP UNIT) command. But this "power condition" field
 * will take effect only when its sent to "UFS device" well known logical unit
@@ -6587,8 +6591,8 @@ static void ufshcd_set_active_icc_lvl(struct ufs_hba *hba)
 * Block) LU so user space process can control this LU. User space may also
 * want to have access to BOOT LU.

 * This function adds scsi device instances for each of all well known LUs
 * (except "REPORT LUNS" LU).
 * This function tries to add scsi device instances for each of all well known
 * LUs (except "REPORT LUNS" LU) depending on device class.
 *
 * Returns zero on success (all required W-LUs are added successfully),
 * non-zero error value on failure (if failed to add any of the required W-LU).
@@ -6598,34 +6602,58 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba)
	int ret = 0;
	struct scsi_device *sdev_rpmb;
	struct scsi_device *sdev_boot;
	bool is_bootable_dev = false;
	bool is_embedded_dev = false;

	if ((hba->dev_info.b_device_sub_class == UFS_DEV_EMBEDDED_BOOTABLE) ||
	    (hba->dev_info.b_device_sub_class == UFS_DEV_REMOVABLE_BOOTABLE))
		is_bootable_dev = true;

	if ((hba->dev_info.b_device_sub_class == UFS_DEV_EMBEDDED_BOOTABLE) ||
	    (hba->dev_info.b_device_sub_class == UFS_DEV_EMBEDDED_NON_BOOTABLE))
		is_embedded_dev = true;

	hba->sdev_ufs_device = __scsi_add_device(hba->host, 0, 0,
		ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_UFS_DEVICE_WLUN), NULL);
	if (IS_ERR(hba->sdev_ufs_device)) {
		ret = PTR_ERR(hba->sdev_ufs_device);
		dev_err(hba->dev, "%s: failed adding DEVICE_WLUN. ret %d\n",
			__func__, ret);
		hba->sdev_ufs_device = NULL;
		goto out;
	}
	scsi_device_put(hba->sdev_ufs_device);

	if (is_bootable_dev) {
		sdev_boot = __scsi_add_device(hba->host, 0, 0,
		ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_BOOT_WLUN), NULL);
			ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_BOOT_WLUN),
			NULL);

		if (IS_ERR(sdev_boot)) {
			dev_err(hba->dev, "%s: failed adding BOOT_WLUN. ret %d\n",
				__func__, ret);
			ret = PTR_ERR(sdev_boot);
			goto remove_sdev_ufs_device;
		}
		scsi_device_put(sdev_boot);
	}

	if (is_embedded_dev) {
		sdev_rpmb = __scsi_add_device(hba->host, 0, 0,
		ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_RPMB_WLUN), NULL);
			ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_RPMB_WLUN),
			NULL);
		if (IS_ERR(sdev_rpmb)) {
			dev_err(hba->dev, "%s: failed adding RPMB_WLUN. ret %d\n",
				__func__, ret);
			ret = PTR_ERR(sdev_rpmb);
			goto remove_sdev_boot;
		}
		scsi_device_put(sdev_rpmb);
	}
	goto out;

remove_sdev_boot:
	if (is_bootable_dev)
		scsi_remove_device(sdev_boot);
remove_sdev_ufs_device:
	scsi_remove_device(hba->sdev_ufs_device);
@@ -6955,6 +6983,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
	if (ret)
		goto out;

	/* clear any previous UFS device information */
	memset(&hba->dev_info, 0, sizeof(hba->dev_info));

	/* cache important parameters from device descriptor for later use */
	ret = ufs_read_device_desc_data(hba);
	if (ret)
@@ -7009,8 +7040,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
	if (!ufshcd_eh_in_progress(hba) && !hba->pm_op_in_progress) {
		bool flag;

		/* clear any previous UFS device information */
		memset(&hba->dev_info, 0, sizeof(hba->dev_info));
		if (!ufshcd_query_flag_retry(hba, UPIU_QUERY_OPCODE_READ_FLAG,
				QUERY_FLAG_IDN_PWR_ON_WPE, &flag))
			hba->dev_info.f_power_on_wp_en = flag;