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

Commit 01cdc7fd authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "scsi: ufs: dump device descriptor info via debugfs"

parents 5bb9df4e b989580a
Loading
Loading
Loading
Loading
+105 −0
Original line number Diff line number Diff line
@@ -20,6 +20,17 @@
#include <linux/random.h>
#include "debugfs.h"

enum field_width {
	BYTE	= 1,
	WORD	= 2,
};

struct desc_field_offset {
	char *name;
	int offset;
	enum field_width width_byte;
};

#ifdef CONFIG_UFS_FAULT_INJECTION

#define INJECT_COMMAND_HANG (0x0)
@@ -306,6 +317,79 @@ static const struct file_operations ufsdbg_host_regs_fops = {
	.read		= seq_read,
};

static int ufsdbg_dump_device_desc_show(struct seq_file *file, void *data)
{
	int err = 0;
	int buff_len = QUERY_DESC_DEVICE_MAX_SIZE;
	u8 desc_buf[QUERY_DESC_DEVICE_MAX_SIZE];
	struct ufs_hba *hba = (struct ufs_hba *)file->private;

	struct desc_field_offset device_desc_field_name[] = {
		{"bLength",		0x00, BYTE},
		{"bDescriptorType",	0x01, BYTE},
		{"bDevice",		0x02, BYTE},
		{"bDeviceClass",	0x03, BYTE},
		{"bDeviceSubClass",	0x04, BYTE},
		{"bProtocol",		0x05, BYTE},
		{"bNumberLU",		0x06, BYTE},
		{"bNumberWLU",		0x07, BYTE},
		{"bBootEnable",		0x08, BYTE},
		{"bDescrAccessEn",	0x09, BYTE},
		{"bInitPowerMode",	0x0A, BYTE},
		{"bHighPriorityLUN",	0x0B, BYTE},
		{"bSecureRemovalType",	0x0C, BYTE},
		{"bSecurityLU",		0x0D, BYTE},
		{"Reserved",		0x0E, BYTE},
		{"bInitActiveICCLevel",	0x0F, BYTE},
		{"wSpecVersion",	0x10, WORD},
		{"wManufactureDate",	0x12, WORD},
		{"iManufactureName",	0x14, BYTE},
		{"iProductName",	0x15, BYTE},
		{"iSerialNumber",	0x16, BYTE},
		{"iOemID",		0x17, BYTE},
		{"wManufactureID",	0x18, WORD},
		{"bUD0BaseOffset",	0x1A, BYTE},
		{"bUDConfigPLength",	0x1B, BYTE},
		{"bDeviceRTTCap",	0x1C, BYTE},
		{"wPeriodicRTCUpdate",	0x1D, WORD}
	};

	pm_runtime_get_sync(hba->dev);
	err = ufshcd_read_device_desc(hba, desc_buf, buff_len);
	pm_runtime_put_sync(hba->dev);

	if (!err) {
		int i;
		struct desc_field_offset *tmp;
		for (i = 0; i < ARRAY_SIZE(device_desc_field_name); ++i) {
			tmp = &device_desc_field_name[i];

			if (tmp->width_byte == BYTE) {
				seq_printf(file,
					   "Device Descriptor[Byte offset 0x%x]: %s = 0x%x\n",
					   tmp->offset,
					   tmp->name,
					   (u8)desc_buf[tmp->offset]);
			} else if (tmp->width_byte == WORD) {
				seq_printf(file,
					   "Device Descriptor[Byte offset 0x%x]: %s = 0x%x\n",
					   tmp->offset,
					   tmp->name,
					   *(u16 *)&desc_buf[tmp->offset]);
			} else {
				seq_printf(file,
				"Device Descriptor[offset 0x%x]: %s. Wrong Width = %d",
				tmp->offset, tmp->name, tmp->width_byte);
			}
		}
	} else {
		seq_printf(file, "Reading Device Descriptor failed. err = %d\n",
			   err);
	}

	return err;
}

static int ufsdbg_show_hba_show(struct seq_file *file, void *data)
{
	struct ufs_hba *hba = (struct ufs_hba *)file->private;
@@ -347,6 +431,17 @@ static const struct file_operations ufsdbg_show_hba_fops = {
	.read		= seq_read,
};

static int ufsdbg_dump_device_desc_open(struct inode *inode, struct file *file)
{
	return single_open(file,
			   ufsdbg_dump_device_desc_show, inode->i_private);
}

static const struct file_operations ufsdbg_dump_device_desc = {
	.open		= ufsdbg_dump_device_desc_open,
	.read		= seq_read,
};

void ufsdbg_add_debugfs(struct ufs_hba *hba)
{
	if (!hba) {
@@ -400,6 +495,16 @@ void ufsdbg_add_debugfs(struct ufs_hba *hba)
		goto err;
	}

	hba->debugfs_files.dump_dev_desc =
		debugfs_create_file("dump_device_desc", S_IRUSR,
				    hba->debugfs_files.debugfs_root, hba,
				    &ufsdbg_dump_device_desc);
	if (!hba->debugfs_files.dump_dev_desc) {
		dev_err(hba->dev,
			"%s:  NULL dump_device_desc file, exiting", __func__);
		goto err;
	}

	ufsdbg_setup_fault_injection(hba);

	return;
+21 −0
Original line number Diff line number Diff line
@@ -1729,6 +1729,27 @@ static inline int ufshcd_read_power_desc(struct ufs_hba *hba,
	return err;
}

int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size)
{
	int err = 0;
	int retries;

	for (retries = QUERY_REQ_RETRIES; retries > 0; retries--) {
		/* Read descriptor*/
		err = ufshcd_read_desc(hba,
				       QUERY_DESC_IDN_DEVICE, 0, buf, size);
		if (!err)
			break;
		dev_dbg(hba->dev, "%s: error %d retrying\n", __func__, err);
	}

	if (err)
		dev_err(hba->dev, "%s: reading Device Desc failed. err = %d\n",
			__func__, err);

	return err;
}

/**
 * ufshcd_read_unit_desc_param - read the specified unit descriptor parameter
 * @hba: Pointer to adapter instance
+3 −0
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@ struct debugfs_files {
	struct dentry *tag_stats;
	struct dentry *show_hba;
	struct dentry *host_regs;
	struct dentry *dump_dev_desc;
#ifdef CONFIG_UFS_FAULT_INJECTION
	struct fault_attr fail_attr;
#endif
@@ -552,6 +553,8 @@ static inline int ufshcd_dme_peer_get(struct ufs_hba *hba,
	return ufshcd_dme_get_attr(hba, attr_sel, mib_val, DME_PEER);
}

int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size);

/* variant specific ops structures */
#ifdef CONFIG_SCSI_UFS_MSM
extern const struct ufs_hba_variant_ops ufs_hba_msm_vops;