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

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

Merge "scsi: ufs: read device descriptor once" into msm-4.8

parents 17876b2e 344c16c9
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -495,7 +495,14 @@ struct ufs_vreg_info {
};

struct ufs_dev_info {
	/* device descriptor info */
	u8	b_device_sub_class;
	u16	w_manufacturer_id;
	u8	i_product_name;

	/* query flags */
	bool f_power_on_wp_en;

	/* Keeps information if any of the LU is power on write protected */
	bool is_lu_power_on_wp;
};
+16 −48
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -34,73 +34,41 @@ static struct ufs_card_fix ufs_fixups[] = {
	END_FIX
};

static int ufs_get_device_info(struct ufs_hba *hba,
				struct ufs_card_info *card_data)
void ufs_advertise_fixup_device(struct ufs_hba *hba)
{
	int err;
	u8 model_index;
	u8 str_desc_buf[QUERY_DESC_STRING_MAX_SIZE + 1];
	u8 desc_buf[QUERY_DESC_DEVICE_MAX_SIZE];
	char *model;
	struct ufs_card_fix *f;

	err = ufshcd_read_device_desc(hba, desc_buf,
					QUERY_DESC_DEVICE_MAX_SIZE);
	if (err)
	model = kmalloc(MAX_MODEL_LEN + 1, GFP_KERNEL);
	if (!model)
		goto out;

	/*
	 * getting vendor (manufacturerID) and Bank Index in big endian
	 * format
	 */
	card_data->wmanufacturerid = desc_buf[DEVICE_DESC_PARAM_MANF_ID] << 8 |
				     desc_buf[DEVICE_DESC_PARAM_MANF_ID + 1];

	model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME];

	memset(str_desc_buf, 0, QUERY_DESC_STRING_MAX_SIZE);
	err = ufshcd_read_string_desc(hba, model_index, str_desc_buf,
					QUERY_DESC_STRING_MAX_SIZE, ASCII_STD);
	err = ufshcd_read_string_desc(hba, hba->dev_info.i_product_name,
			str_desc_buf, QUERY_DESC_STRING_MAX_SIZE, ASCII_STD);
	if (err)
		goto out;

	str_desc_buf[QUERY_DESC_STRING_MAX_SIZE] = '\0';
	strlcpy(card_data->model, (str_desc_buf + QUERY_DESC_HDR_SIZE),
	strlcpy(model, (str_desc_buf + QUERY_DESC_HDR_SIZE),
		min_t(u8, str_desc_buf[QUERY_DESC_LENGTH_OFFSET],
		      MAX_MODEL_LEN));
	/* Null terminate the model string */
	card_data->model[MAX_MODEL_LEN] = '\0';

out:
	return err;
}

void ufs_advertise_fixup_device(struct ufs_hba *hba)
{
	int err;
	struct ufs_card_fix *f;
	struct ufs_card_info card_data;

	card_data.wmanufacturerid = 0;
	card_data.model = kmalloc(MAX_MODEL_LEN + 1, GFP_KERNEL);
	if (!card_data.model)
		goto out;

	/* get device data*/
	err = ufs_get_device_info(hba, &card_data);
	if (err) {
		dev_err(hba->dev, "%s: Failed getting device info\n", __func__);
		goto out;
	}
	model[MAX_MODEL_LEN] = '\0';

	for (f = ufs_fixups; f->quirk; f++) {
		/* if same wmanufacturerid */
		if (((f->card.wmanufacturerid == card_data.wmanufacturerid) ||
		     (f->card.wmanufacturerid == UFS_ANY_VENDOR)) &&
		if (((f->w_manufacturer_id ==
			hba->dev_info.w_manufacturer_id) ||
		     (f->w_manufacturer_id == UFS_ANY_VENDOR)) &&
		    /* and same model */
		    (STR_PRFX_EQUAL(f->card.model, card_data.model) ||
		     !strcmp(f->card.model, UFS_ANY_MODEL)))
		    (STR_PRFX_EQUAL(f->model, model) ||
		     !strcmp(f->model, UFS_ANY_MODEL)))
			/* update quirks */
			hba->dev_quirks |= f->quirk;
	}
out:
	kfree(card_data.model);
	kfree(model);
}
+6 −15
Original line number Diff line number Diff line
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -30,33 +30,24 @@
#define UFS_MODEL_TOSHIBA_32GB "THGLF2G8D4KBADR"
#define UFS_MODEL_TOSHIBA_64GB "THGLF2G9D8KBADG"

/**
 * ufs_card_info - ufs device details
 * @wmanufacturerid: card details
 * @model: card model
 */
struct ufs_card_info {
	u16 wmanufacturerid;
	char *model;
};

/**
 * ufs_card_fix - ufs device quirk info
 * @card: ufs card details
 * @quirk: device quirk
 */
struct ufs_card_fix {
	struct ufs_card_info card;
	u16 w_manufacturer_id;
	char *model;
	unsigned int quirk;
};

#define END_FIX { { 0 } , 0 }
#define END_FIX { 0 }

/* add specific device quirk */
#define UFS_FIX(_vendor, _model, _quirk) \
		{						  \
				.card.wmanufacturerid = (_vendor),\
				.card.model = (_model),		  \
				.w_manufacturer_id = (_vendor),\
				.model = (_model),		  \
				.quirk = (_quirk),		  \
		}

+28 −0
Original line number Diff line number Diff line
@@ -6895,6 +6895,29 @@ static int ufshcd_set_dev_ref_clk(struct ufs_hba *hba)
	return err;
}

static int ufs_read_device_desc_data(struct ufs_hba *hba)
{
	int err;
	u8 desc_buf[QUERY_DESC_DEVICE_MAX_SIZE];

	err = ufshcd_read_device_desc(hba, desc_buf, sizeof(desc_buf));
	if (err)
		return err;

	/*
	 * getting vendor (manufacturerID) and Bank Index in big endian
	 * format
	 */
	hba->dev_info.w_manufacturer_id =
		desc_buf[DEVICE_DESC_PARAM_MANF_ID] << 8 |
		desc_buf[DEVICE_DESC_PARAM_MANF_ID + 1];
	hba->dev_info.b_device_sub_class =
		desc_buf[DEVICE_DESC_PARAM_DEVICE_SUB_CLASS];
	hba->dev_info.i_product_name = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME];

	return 0;
}

/**
 * ufshcd_probe_hba - probe hba to detect device and initialize
 * @hba: per-adapter instance
@@ -6932,6 +6955,11 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
	if (ret)
		goto out;

	/* cache important parameters from device descriptor for later use */
	ret = ufs_read_device_desc_data(hba);
	if (ret)
		goto out;

	ufs_advertise_fixup_device(hba);
	ufshcd_tune_unipro_params(hba);