mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
mtd: virt_mtd: add sysfs nodes
Add mechanism to read manufacture_id, device_id size and ecc_info through guest vm add the sysfs nodes to achieve this. JIRA SSV-12115 Signed-off-by: Vishwaroop A <va@nvidia.com> Change-Id: Ib9311c2da8c4f5ccf1efcc7aeb16026bc5159c0c Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3183733 (cherry picked from commit 402b93d8537cc51b56288de1dee729b30b663368) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3198295 GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com> Reviewed-by: Bibek Basu <bbasu@nvidia.com>
This commit is contained in:
@@ -470,9 +470,96 @@ static ssize_t vmtd_phys_base_show(struct device *dev,
|
|||||||
}
|
}
|
||||||
static DEVICE_ATTR(phys_base, 0444, vmtd_phys_base_show, NULL);
|
static DEVICE_ATTR(phys_base, 0444, vmtd_phys_base_show, NULL);
|
||||||
|
|
||||||
|
static ssize_t manufacturer_id_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct vmtd_dev *vmtddev = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
return sprintf(buf, "0x%x\n", vmtddev->config.mtd_config.manufacturer_id);
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RO(manufacturer_id);
|
||||||
|
|
||||||
|
static ssize_t device_id_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct vmtd_dev *vmtddev = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
return sprintf(buf, "0x%x\n", vmtddev->config.mtd_config.device_id);
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RO(device_id);
|
||||||
|
|
||||||
|
static ssize_t qspi_device_size_bytes_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct vmtd_dev *vmtddev = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
return sprintf(buf, "%u\n", (unsigned int)vmtddev->config.mtd_config.qspi_device_size_bytes);
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RO(qspi_device_size_bytes);
|
||||||
|
|
||||||
|
static ssize_t ecc_status_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct vmtd_dev *vmtddev = dev_get_drvdata(dev);
|
||||||
|
struct vs_request *vs_req;
|
||||||
|
int32_t ret;
|
||||||
|
struct vs_mtd_ecc_response ecc_response;
|
||||||
|
|
||||||
|
vs_req = (struct vs_request *)vmtddev->cmd_frame;
|
||||||
|
vs_req->type = VS_DATA_REQ;
|
||||||
|
vs_req->mtddev_req.req_op = VS_MTD_ECC;
|
||||||
|
vs_req->mtddev_req.mtd_req.offset = 0;
|
||||||
|
vs_req->mtddev_req.mtd_req.size = 0;
|
||||||
|
vs_req->mtddev_req.mtd_req.data_offset = 0;
|
||||||
|
vs_req->req_id = 0;
|
||||||
|
|
||||||
|
ret = vmtd_process_request(vmtddev, vs_req);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(vmtddev->device, "Read ECC Failed\n");
|
||||||
|
return snprintf(buf, PAGE_SIZE, "Error reading ECC status\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ecc_response = vs_req->mtddev_resp.ecc_resp;
|
||||||
|
vs_req->mtddev_req.stored_ecc_status = ecc_response.status;
|
||||||
|
vs_req->mtddev_req.stored_failed_chunk_addr = ecc_response.failed_chunk_addr;
|
||||||
|
|
||||||
|
switch (ecc_response.status) {
|
||||||
|
case ECC_NO_ERROR:
|
||||||
|
return sprintf(buf, "0x%x\n", ECC_NO_ERROR);
|
||||||
|
case ECC_ONE_BIT_CORRECTED:
|
||||||
|
return sprintf(buf, "0x%x\n", ECC_ONE_BIT_CORRECTED);
|
||||||
|
case ECC_TWO_BIT_ERROR:
|
||||||
|
return sprintf(buf, "0x%x\n", ECC_TWO_BIT_ERROR);
|
||||||
|
case ECC_DISABLED:
|
||||||
|
return sprintf(buf, "0x%x\n", ECC_DISABLED);
|
||||||
|
default:
|
||||||
|
return snprintf(buf, PAGE_SIZE, "ECC Status: Unknown error\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RO(ecc_status);
|
||||||
|
|
||||||
|
static ssize_t failure_chunk_addr_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct vmtd_dev *vmtddev = dev_get_drvdata(dev);
|
||||||
|
struct vs_request *vs_req = (struct vs_request *)vmtddev->cmd_frame;
|
||||||
|
|
||||||
|
if (vs_req->mtddev_req.stored_ecc_status == ECC_NO_ERROR)
|
||||||
|
return sprintf(buf, "0x0\n");
|
||||||
|
else
|
||||||
|
return snprintf(buf, PAGE_SIZE, "0x%x\n", vs_req->mtddev_req.stored_failed_chunk_addr);
|
||||||
|
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RO(failure_chunk_addr);
|
||||||
|
|
||||||
static const struct attribute *vmtd_storage_attrs[] = {
|
static const struct attribute *vmtd_storage_attrs[] = {
|
||||||
&dev_attr_phys_dev.attr,
|
&dev_attr_phys_dev.attr,
|
||||||
&dev_attr_phys_base.attr,
|
&dev_attr_phys_base.attr,
|
||||||
|
&dev_attr_manufacturer_id.attr,
|
||||||
|
&dev_attr_device_id.attr,
|
||||||
|
&dev_attr_qspi_device_size_bytes.attr,
|
||||||
|
&dev_attr_ecc_status.attr,
|
||||||
|
&dev_attr_failure_chunk_addr.attr,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,52 @@ enum mtd_cmd_op {
|
|||||||
VS_MTD_WRITE = 2,
|
VS_MTD_WRITE = 2,
|
||||||
VS_MTD_ERASE = 3,
|
VS_MTD_ERASE = 3,
|
||||||
VS_MTD_IOCTL = 4,
|
VS_MTD_IOCTL = 4,
|
||||||
|
VS_MTD_ECC = 5,
|
||||||
VS_MTD_INVAL_REQ = 32,
|
VS_MTD_INVAL_REQ = 32,
|
||||||
VS_UNKNOWN_MTD_CMD = 0xffffffff,
|
VS_UNKNOWN_MTD_CMD = 0xffffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/**
|
||||||
|
* @brief no error detected for ECC 0x800 register.
|
||||||
|
*/
|
||||||
|
ECC_NO_ERROR = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief one bit error corrected for ECC 0x800 register.
|
||||||
|
*/
|
||||||
|
ECC_ONE_BIT_CORRECTED = 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief two bit error detected for ECC 0x800 register.
|
||||||
|
*/
|
||||||
|
ECC_TWO_BIT_ERROR = 2,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ECC is disabled 0x800 register.
|
||||||
|
*/
|
||||||
|
ECC_DISABLED = 3,
|
||||||
|
} qspi_ecc_err;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QSPI ecc status
|
||||||
|
* A structure contains information related to ecc
|
||||||
|
* read values
|
||||||
|
*/
|
||||||
|
typedef struct NvQspi_ecc_status {
|
||||||
|
/**
|
||||||
|
* @brief read ECC error status.
|
||||||
|
*/
|
||||||
|
qspi_ecc_err status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief if 1 or 2 bit error, this will
|
||||||
|
* hold valid failed chunk address.
|
||||||
|
*/
|
||||||
|
uint32_t failed_chunk_addr;
|
||||||
|
} NvQspi_ecc_status;
|
||||||
|
|
||||||
|
|
||||||
/* MTD device request Operation type features supported */
|
/* MTD device request Operation type features supported */
|
||||||
#define VS_MTD_READ_OP_F (1 << VS_MTD_READ)
|
#define VS_MTD_READ_OP_F (1 << VS_MTD_READ)
|
||||||
#define VS_MTD_WRITE_OP_F (1 << VS_MTD_WRITE)
|
#define VS_MTD_WRITE_OP_F (1 << VS_MTD_WRITE)
|
||||||
@@ -118,6 +160,9 @@ struct vs_mtddev_request {
|
|||||||
struct vs_mtd_request mtd_req;
|
struct vs_mtd_request mtd_req;
|
||||||
struct vs_ioctl_request ioctl_req;
|
struct vs_ioctl_request ioctl_req;
|
||||||
};
|
};
|
||||||
|
uint32_t stored_ecc_status; /* Field to store ECC status */
|
||||||
|
|
||||||
|
uint32_t stored_failed_chunk_addr; /* field to store failed chunk address */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vs_blk_response {
|
struct vs_blk_response {
|
||||||
@@ -142,10 +187,30 @@ struct vs_blkdev_response {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vs_mtd_ecc_response {
|
||||||
|
/** Status code returned as part of response message of MTD requests.
|
||||||
|
* Status code value is "0" for success and "< 0" for failure
|
||||||
|
* This value of this member is ignored in the MTD request message.
|
||||||
|
*/
|
||||||
|
int32_t status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read ECC error status.
|
||||||
|
*/
|
||||||
|
uint32_t ecc_status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If 1 or 2 bit error, this will
|
||||||
|
* hold valid failed chunk address.
|
||||||
|
*/
|
||||||
|
uint32_t failed_chunk_addr;
|
||||||
|
};
|
||||||
|
|
||||||
struct vs_mtddev_response {
|
struct vs_mtddev_response {
|
||||||
union {
|
union {
|
||||||
struct vs_mtd_response mtd_resp;
|
struct vs_mtd_response mtd_resp;
|
||||||
struct vs_ioctl_response ioctl_resp;
|
struct vs_ioctl_response ioctl_resp;
|
||||||
|
struct vs_mtd_ecc_response ecc_resp;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -176,6 +241,9 @@ struct vs_mtd_dev_config {
|
|||||||
device*/
|
device*/
|
||||||
uint32_t req_ops_supported; /* Allowed operations by requests */
|
uint32_t req_ops_supported; /* Allowed operations by requests */
|
||||||
uint64_t size; /* Total number of bytes */
|
uint64_t size; /* Total number of bytes */
|
||||||
|
uint32_t manufacturer_id;
|
||||||
|
uint32_t device_id;
|
||||||
|
uint32_t qspi_device_size_bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Physical device types */
|
/* Physical device types */
|
||||||
@@ -209,6 +277,7 @@ struct vs_config_info {
|
|||||||
uint32_t storage_type;
|
uint32_t storage_type;
|
||||||
uint32_t priority;
|
uint32_t priority;
|
||||||
uint8_t speed_mode[SPEED_MODE_MAX_LEN];
|
uint8_t speed_mode[SPEED_MODE_MAX_LEN];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vs_request {
|
struct vs_request {
|
||||||
|
|||||||
Reference in New Issue
Block a user