Loading drivers/scsi/sg.c +5 −0 Original line number Diff line number Diff line Loading @@ -433,6 +433,9 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) struct sg_header *old_hdr = NULL; int retval = 0; if (unlikely(segment_eq(get_fs(), KERNEL_DS))) return -EINVAL; /* * This could cause a response to be stranded. Close the associated * file descriptor to free up any resources being held. Loading Loading @@ -979,6 +982,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) * return an error value. So returning '0' to keep compability * with legacy applications. */ mutex_lock(&sfp->parentdp->open_rel_lock); mutex_unlock(&sfp->parentdp->open_rel_lock); return 0; case SG_GET_LOW_DMA: return put_user((int) sdp->device->host->unchecked_isa_dma, ip); Loading drivers/scsi/ufs/Kconfig +7 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,13 @@ config SCSI_UFS_QCOM_ICE Select this if you have ICE supported for UFS on QCOM chipset. If unsure, say N. config SCSI_UFS_RESTRICT_TX_LANES bool "Restrict the number of TX lanes to 1" default n help Say Y here to restrict the number of TX lanes to 1. This will save the power consumption in exchange for the write performance. config SCSI_UFS_TEST tristate "Universal Flash Storage host controller driver unit-tests" Loading drivers/scsi/ufs/ufs-debugfs.c +198 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,11 @@ * of the driver from userspace. * */ /* * NOTE: This file has been modified by Sony Mobile Communications Inc. * Modifications are Copyright (c) 2017 Sony Mobile Communications Inc, * and licensed under the license of the file. */ #include <linux/random.h> #include "ufs-debugfs.h" Loading @@ -25,6 +30,7 @@ enum field_width { BYTE = 1, WORD = 2, DWORD = 4, }; struct desc_field_offset { Loading Loading @@ -366,6 +372,7 @@ static const struct file_operations ufsdbg_err_inj_scenario_ops = { .open = ufsdbg_err_inj_scenario_open, .read = seq_read, .write = ufsdbg_err_inj_scenario_write, .release = single_release, }; static int ufsdbg_err_inj_stats_read(struct seq_file *file, void *data) Loading Loading @@ -407,6 +414,7 @@ static const struct file_operations ufsdbg_err_inj_stats_ops = { .open = ufsdbg_err_inj_stats_open, .read = seq_read, .write = ufsdbg_err_inj_stats_write, .release = single_release, }; static void ufsdbg_setup_fault_injection(struct ufs_hba *hba) Loading Loading @@ -591,6 +599,7 @@ static const struct file_operations ufsdbg_tag_stats_fops = { .open = ufsdbg_tag_stats_open, .read = seq_read, .write = ufsdbg_tag_stats_write, .release = single_release, }; static int ufsdbg_query_stats_show(struct seq_file *file, void *data) Loading Loading @@ -662,6 +671,7 @@ static const struct file_operations ufsdbg_query_stats_fops = { .open = ufsdbg_query_stats_open, .read = seq_read, .write = ufsdbg_query_stats_write, .release = single_release, }; static int ufsdbg_err_stats_show(struct seq_file *file, void *data) Loading Loading @@ -766,6 +776,7 @@ static const struct file_operations ufsdbg_err_stats_fops = { .open = ufsdbg_err_stats_open, .read = seq_read, .write = ufsdbg_err_stats_write, .release = single_release, }; static int ufshcd_init_statistics(struct ufs_hba *hba) Loading Loading @@ -845,6 +856,7 @@ static int ufsdbg_host_regs_open(struct inode *inode, struct file *file) static const struct file_operations ufsdbg_host_regs_fops = { .open = ufsdbg_host_regs_open, .read = seq_read, .release = single_release, }; static int ufsdbg_dump_device_desc_show(struct seq_file *file, void *data) Loading Loading @@ -881,7 +893,15 @@ static int ufsdbg_dump_device_desc_show(struct seq_file *file, void *data) {"bUD0BaseOffset", 0x1A, BYTE}, {"bUDConfigPLength", 0x1B, BYTE}, {"bDeviceRTTCap", 0x1C, BYTE}, {"wPeriodicRTCUpdate", 0x1D, WORD} {"wPeriodicRTCUpdate", 0x1D, WORD}, {"bUFSFeaturesSupport", 0x1F, BYTE}, {"bFFUTimeout", 0x20, BYTE}, {"bQueueDepth", 0x21, BYTE}, {"wDeviceVersion", 0x22, WORD}, {"bNumSecureWPArea", 0x24, BYTE}, {"dPSAMaxDataSize", 0x25, DWORD}, {"bPSAStateTimeout", 0x29, BYTE}, {"iProductRevisionLevel", 0x2A, BYTE}, }; pm_runtime_get_sync(hba->dev); Loading @@ -906,6 +926,12 @@ static int ufsdbg_dump_device_desc_show(struct seq_file *file, void *data) tmp->offset, tmp->name, *(u16 *)&desc_buf[tmp->offset]); } else if (tmp->width_byte == DWORD) { seq_printf(file, "Device Descriptor[Byte offset 0x%x]: %s = 0x%x\n", tmp->offset, tmp->name, *(u32 *)&desc_buf[tmp->offset]); } else { seq_printf(file, "Device Descriptor[offset 0x%x]: %s. Wrong Width = %d", Loading Loading @@ -965,6 +991,7 @@ static int ufsdbg_show_hba_open(struct inode *inode, struct file *file) static const struct file_operations ufsdbg_show_hba_fops = { .open = ufsdbg_show_hba_open, .read = seq_read, .release = single_release, }; static int ufsdbg_dump_device_desc_open(struct inode *inode, struct file *file) Loading @@ -976,6 +1003,143 @@ static int ufsdbg_dump_device_desc_open(struct inode *inode, struct file *file) static const struct file_operations ufsdbg_dump_device_desc = { .open = ufsdbg_dump_device_desc_open, .read = seq_read, .release = single_release, }; static int ufsdbg_dump_device_health_desc_show(struct seq_file *file, void *data) { int err = 0; int buff_len = QUERY_DESC_DEVICE_HEALTH_MAX_SIZE; u8 desc_buf[QUERY_DESC_DEVICE_HEALTH_MAX_SIZE]; struct ufs_hba *hba = (struct ufs_hba *)file->private; pm_runtime_get_sync(hba->dev); err = ufshcd_read_device_health_desc(hba, desc_buf, buff_len); pm_runtime_put_sync(hba->dev); if (!err) { int i; for (i = 0; i < QUERY_DESC_DEVICE_HEALTH_MAX_SIZE; ++i) { seq_printf(file, "%02x", desc_buf[i]); } } else { seq_printf(file, "Reading Device Health Descriptor failed. err = %d\n", err); } return err; } static int ufsdbg_dump_device_health_desc_open(struct inode *inode, struct file *file) { return single_open(file, ufsdbg_dump_device_health_desc_show, inode->i_private); } static const struct file_operations ufsdbg_dump_device_health_desc = { .open = ufsdbg_dump_device_health_desc_open, .read = seq_read, .release = single_release, }; static int ufsdbg_dump_fw_revision_show(struct seq_file *file, void *data) { int err = 0; u8 index; u8 desc_buf[QUERY_DESC_DEVICE_MAX_SIZE]; u8 str_desc_buf[QUERY_DESC_STRING_MAX_SIZE + 1]; struct ufs_hba *hba = (struct ufs_hba *)file->private; pm_runtime_get_sync(hba->dev); err = ufshcd_read_device_desc(hba, desc_buf, QUERY_DESC_DEVICE_MAX_SIZE); if (err) { seq_printf(file, "Reading Device Descriptor failed. err = %d\n", err); goto out; } index = desc_buf[DEVICE_DESC_PARAM_PRODUCT_REVISION]; memset(str_desc_buf, 0, QUERY_DESC_STRING_MAX_SIZE + 1); err = ufshcd_read_string_desc(hba, index, str_desc_buf, QUERY_DESC_STRING_MAX_SIZE, ASCII_STD); if (err) { seq_printf(file, "Reading String Descriptor failed. err = %d\n", err); } else { seq_printf(file, "FW revision = %s\n", &str_desc_buf[QUERY_DESC_HDR_SIZE]); } out: pm_runtime_put_sync(hba->dev); return err; } static int ufsdbg_dump_fw_revision_open(struct inode *inode, struct file *file) { return single_open(file, ufsdbg_dump_fw_revision_show, inode->i_private); } static const struct file_operations ufsdbg_dump_fw_revision = { .open = ufsdbg_dump_fw_revision_open, .read = seq_read, .release = single_release, }; static int ufsdbg_dump_serial_show(struct seq_file *file, void *data) { int err = 0; int i, len = 0; u8 index; u8 desc_buf[QUERY_DESC_DEVICE_MAX_SIZE]; u8 str_desc_buf[QUERY_DESC_STRING_MAX_SIZE]; struct ufs_hba *hba = (struct ufs_hba *)file->private; pm_runtime_get_sync(hba->dev); err = ufshcd_read_device_desc(hba, desc_buf, QUERY_DESC_DEVICE_MAX_SIZE); if (err) { seq_printf(file, "Reading Device Descriptor failed. err = %d\n", err); goto out; } index = desc_buf[DEVICE_DESC_PARAM_SN]; memset(str_desc_buf, 0, QUERY_DESC_STRING_MAX_SIZE); err = ufshcd_read_string_desc(hba, index, str_desc_buf, QUERY_DESC_STRING_MAX_SIZE, UTF16_STD); if (err) { seq_printf(file, "Reading String Descriptor failed. err = %d\n", err); goto out; } len = (int)str_desc_buf[QUERY_DESC_LENGTH_OFFSET]; if (len > QUERY_DESC_STRING_MAX_SIZE) len = QUERY_DESC_STRING_MAX_SIZE; seq_puts(file, "Serial = "); for (i = QUERY_DESC_HDR_SIZE; i < len; i++) seq_printf(file, "%02X", str_desc_buf[i]); seq_puts(file, "\n"); out: pm_runtime_put_sync(hba->dev); return err; } static int ufsdbg_dump_serial_open(struct inode *inode, struct file *file) { return single_open(file, ufsdbg_dump_serial_show, inode->i_private); } static const struct file_operations ufsdbg_dump_serial = { .open = ufsdbg_dump_serial_open, .read = seq_read, .release = single_release, }; static int ufsdbg_power_mode_show(struct seq_file *file, void *data) Loading Loading @@ -1214,6 +1378,7 @@ static const struct file_operations ufsdbg_power_mode_desc = { .open = ufsdbg_power_mode_open, .read = seq_read, .write = ufsdbg_power_mode_write, .release = single_release, }; static int ufsdbg_dme_read(void *data, u64 *attr_val, bool peer) Loading Loading @@ -1393,6 +1558,7 @@ static const struct file_operations ufsdbg_req_stats_desc = { .open = ufsdbg_req_stats_open, .read = seq_read, .write = ufsdbg_req_stats_write, .release = single_release, }; Loading Loading @@ -1441,6 +1607,7 @@ static const struct file_operations ufsdbg_reset_controller = { .open = ufsdbg_reset_controller_open, .read = seq_read, .write = ufsdbg_reset_controller_write, .release = single_release, }; static int ufsdbg_clear_err_state(void *data, u64 val) Loading Loading @@ -1649,6 +1816,36 @@ void ufsdbg_add_debugfs(struct ufs_hba *hba) goto err; } hba->debugfs_files.dump_dev_health_desc = debugfs_create_file("dump_device_health_desc", S_IRUSR, hba->debugfs_files.debugfs_root, hba, &ufsdbg_dump_device_health_desc); if (!hba->debugfs_files.dump_dev_health_desc) { dev_err(hba->dev, "%s: NULL dump_device_health_desc file, exiting", __func__); goto err; } hba->debugfs_files.fw_revision = debugfs_create_file("fw_revision", S_IRUSR, hba->debugfs_files.debugfs_root, hba, &ufsdbg_dump_fw_revision); if (!hba->debugfs_files.fw_revision) { dev_err(hba->dev, "%s: NULL fw_revision file, exiting", __func__); goto err; } hba->debugfs_files.serial = debugfs_create_file("serial", S_IRUSR, hba->debugfs_files.debugfs_root, hba, &ufsdbg_dump_serial); if (!hba->debugfs_files.serial) { dev_err(hba->dev, "%s: NULL serial file, exiting", __func__); goto err; } ufsdbg_setup_fault_injection(hba); ufshcd_vops_add_debugfs(hba, hba->debugfs_files.debugfs_root); Loading drivers/scsi/ufs/ufs-qcom-debugfs.c +3 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ static const struct file_operations ufs_qcom_dbg_testbus_cfg_desc = { .open = ufs_qcom_dbg_testbus_cfg_open, .read = seq_read, .write = ufs_qcom_dbg_testbus_cfg_write, .release = single_release, }; static int ufs_qcom_dbg_testbus_bus_read(void *data, u64 *attr_val) Loading Loading @@ -240,6 +241,7 @@ static int ufs_qcom_dbg_dbg_regs_open(struct inode *inode, static const struct file_operations ufs_qcom_dbg_dbg_regs_desc = { .open = ufs_qcom_dbg_dbg_regs_open, .read = seq_read, .release = single_release, }; static int ufs_qcom_dbg_pm_qos_show(struct seq_file *file, void *data) Loading Loading @@ -273,6 +275,7 @@ static int ufs_qcom_dbg_pm_qos_open(struct inode *inode, static const struct file_operations ufs_qcom_dbg_pm_qos_desc = { .open = ufs_qcom_dbg_pm_qos_open, .read = seq_read, .release = single_release, }; void ufs_qcom_dbg_add_debugfs(struct ufs_hba *hba, struct dentry *root) Loading drivers/scsi/ufs/ufs-qcom-ice.c +16 −2 Original line number Diff line number Diff line Loading @@ -10,6 +10,11 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* * NOTE: This file has been modified by Sony Mobile Communications Inc. * Modifications are Copyright (c) 2017 Sony Mobile Communications Inc, * and licensed under the license of the file. */ #include <linux/io.h> #include <linux/of.h> Loading @@ -27,6 +32,8 @@ #define UFS_QCOM_ICE_DEFAULT_DBG_PRINT_EN 0 static struct workqueue_struct *ice_workqueue; static void ufs_qcom_ice_dump_regs(struct ufs_qcom_host *qcom_host, int offset, int len, char *prefix) { Loading Loading @@ -224,6 +231,13 @@ int ufs_qcom_ice_init(struct ufs_qcom_host *qcom_host) } qcom_host->dbg_print_en |= UFS_QCOM_ICE_DEFAULT_DBG_PRINT_EN; ice_workqueue = alloc_workqueue("ice-set-key", WQ_MEM_RECLAIM | WQ_HIGHPRI, 0); if (!ice_workqueue) { dev_err(ufs_dev, "%s: workqueue allocation failed.\n", __func__); goto out; } INIT_WORK(&qcom_host->ice_cfg_work, ufs_qcom_ice_cfg_work); out: Loading Loading @@ -284,7 +298,7 @@ int ufs_qcom_ice_req_setup(struct ufs_qcom_host *qcom_host, if (!qcom_host->work_pending) { qcom_host->req_pending = cmd->request; if (!schedule_work( if (!queue_work(ice_workqueue, &qcom_host->ice_cfg_work)) { qcom_host->req_pending = NULL; Loading Loading @@ -404,7 +418,7 @@ int ufs_qcom_ice_cfg_start(struct ufs_qcom_host *qcom_host, if (!qcom_host->work_pending) { qcom_host->req_pending = cmd->request; if (!schedule_work( if (!queue_work(ice_workqueue, &qcom_host->ice_cfg_work)) { qcom_host->req_pending = NULL; Loading Loading
drivers/scsi/sg.c +5 −0 Original line number Diff line number Diff line Loading @@ -433,6 +433,9 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) struct sg_header *old_hdr = NULL; int retval = 0; if (unlikely(segment_eq(get_fs(), KERNEL_DS))) return -EINVAL; /* * This could cause a response to be stranded. Close the associated * file descriptor to free up any resources being held. Loading Loading @@ -979,6 +982,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) * return an error value. So returning '0' to keep compability * with legacy applications. */ mutex_lock(&sfp->parentdp->open_rel_lock); mutex_unlock(&sfp->parentdp->open_rel_lock); return 0; case SG_GET_LOW_DMA: return put_user((int) sdp->device->host->unchecked_isa_dma, ip); Loading
drivers/scsi/ufs/Kconfig +7 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,13 @@ config SCSI_UFS_QCOM_ICE Select this if you have ICE supported for UFS on QCOM chipset. If unsure, say N. config SCSI_UFS_RESTRICT_TX_LANES bool "Restrict the number of TX lanes to 1" default n help Say Y here to restrict the number of TX lanes to 1. This will save the power consumption in exchange for the write performance. config SCSI_UFS_TEST tristate "Universal Flash Storage host controller driver unit-tests" Loading
drivers/scsi/ufs/ufs-debugfs.c +198 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,11 @@ * of the driver from userspace. * */ /* * NOTE: This file has been modified by Sony Mobile Communications Inc. * Modifications are Copyright (c) 2017 Sony Mobile Communications Inc, * and licensed under the license of the file. */ #include <linux/random.h> #include "ufs-debugfs.h" Loading @@ -25,6 +30,7 @@ enum field_width { BYTE = 1, WORD = 2, DWORD = 4, }; struct desc_field_offset { Loading Loading @@ -366,6 +372,7 @@ static const struct file_operations ufsdbg_err_inj_scenario_ops = { .open = ufsdbg_err_inj_scenario_open, .read = seq_read, .write = ufsdbg_err_inj_scenario_write, .release = single_release, }; static int ufsdbg_err_inj_stats_read(struct seq_file *file, void *data) Loading Loading @@ -407,6 +414,7 @@ static const struct file_operations ufsdbg_err_inj_stats_ops = { .open = ufsdbg_err_inj_stats_open, .read = seq_read, .write = ufsdbg_err_inj_stats_write, .release = single_release, }; static void ufsdbg_setup_fault_injection(struct ufs_hba *hba) Loading Loading @@ -591,6 +599,7 @@ static const struct file_operations ufsdbg_tag_stats_fops = { .open = ufsdbg_tag_stats_open, .read = seq_read, .write = ufsdbg_tag_stats_write, .release = single_release, }; static int ufsdbg_query_stats_show(struct seq_file *file, void *data) Loading Loading @@ -662,6 +671,7 @@ static const struct file_operations ufsdbg_query_stats_fops = { .open = ufsdbg_query_stats_open, .read = seq_read, .write = ufsdbg_query_stats_write, .release = single_release, }; static int ufsdbg_err_stats_show(struct seq_file *file, void *data) Loading Loading @@ -766,6 +776,7 @@ static const struct file_operations ufsdbg_err_stats_fops = { .open = ufsdbg_err_stats_open, .read = seq_read, .write = ufsdbg_err_stats_write, .release = single_release, }; static int ufshcd_init_statistics(struct ufs_hba *hba) Loading Loading @@ -845,6 +856,7 @@ static int ufsdbg_host_regs_open(struct inode *inode, struct file *file) static const struct file_operations ufsdbg_host_regs_fops = { .open = ufsdbg_host_regs_open, .read = seq_read, .release = single_release, }; static int ufsdbg_dump_device_desc_show(struct seq_file *file, void *data) Loading Loading @@ -881,7 +893,15 @@ static int ufsdbg_dump_device_desc_show(struct seq_file *file, void *data) {"bUD0BaseOffset", 0x1A, BYTE}, {"bUDConfigPLength", 0x1B, BYTE}, {"bDeviceRTTCap", 0x1C, BYTE}, {"wPeriodicRTCUpdate", 0x1D, WORD} {"wPeriodicRTCUpdate", 0x1D, WORD}, {"bUFSFeaturesSupport", 0x1F, BYTE}, {"bFFUTimeout", 0x20, BYTE}, {"bQueueDepth", 0x21, BYTE}, {"wDeviceVersion", 0x22, WORD}, {"bNumSecureWPArea", 0x24, BYTE}, {"dPSAMaxDataSize", 0x25, DWORD}, {"bPSAStateTimeout", 0x29, BYTE}, {"iProductRevisionLevel", 0x2A, BYTE}, }; pm_runtime_get_sync(hba->dev); Loading @@ -906,6 +926,12 @@ static int ufsdbg_dump_device_desc_show(struct seq_file *file, void *data) tmp->offset, tmp->name, *(u16 *)&desc_buf[tmp->offset]); } else if (tmp->width_byte == DWORD) { seq_printf(file, "Device Descriptor[Byte offset 0x%x]: %s = 0x%x\n", tmp->offset, tmp->name, *(u32 *)&desc_buf[tmp->offset]); } else { seq_printf(file, "Device Descriptor[offset 0x%x]: %s. Wrong Width = %d", Loading Loading @@ -965,6 +991,7 @@ static int ufsdbg_show_hba_open(struct inode *inode, struct file *file) static const struct file_operations ufsdbg_show_hba_fops = { .open = ufsdbg_show_hba_open, .read = seq_read, .release = single_release, }; static int ufsdbg_dump_device_desc_open(struct inode *inode, struct file *file) Loading @@ -976,6 +1003,143 @@ static int ufsdbg_dump_device_desc_open(struct inode *inode, struct file *file) static const struct file_operations ufsdbg_dump_device_desc = { .open = ufsdbg_dump_device_desc_open, .read = seq_read, .release = single_release, }; static int ufsdbg_dump_device_health_desc_show(struct seq_file *file, void *data) { int err = 0; int buff_len = QUERY_DESC_DEVICE_HEALTH_MAX_SIZE; u8 desc_buf[QUERY_DESC_DEVICE_HEALTH_MAX_SIZE]; struct ufs_hba *hba = (struct ufs_hba *)file->private; pm_runtime_get_sync(hba->dev); err = ufshcd_read_device_health_desc(hba, desc_buf, buff_len); pm_runtime_put_sync(hba->dev); if (!err) { int i; for (i = 0; i < QUERY_DESC_DEVICE_HEALTH_MAX_SIZE; ++i) { seq_printf(file, "%02x", desc_buf[i]); } } else { seq_printf(file, "Reading Device Health Descriptor failed. err = %d\n", err); } return err; } static int ufsdbg_dump_device_health_desc_open(struct inode *inode, struct file *file) { return single_open(file, ufsdbg_dump_device_health_desc_show, inode->i_private); } static const struct file_operations ufsdbg_dump_device_health_desc = { .open = ufsdbg_dump_device_health_desc_open, .read = seq_read, .release = single_release, }; static int ufsdbg_dump_fw_revision_show(struct seq_file *file, void *data) { int err = 0; u8 index; u8 desc_buf[QUERY_DESC_DEVICE_MAX_SIZE]; u8 str_desc_buf[QUERY_DESC_STRING_MAX_SIZE + 1]; struct ufs_hba *hba = (struct ufs_hba *)file->private; pm_runtime_get_sync(hba->dev); err = ufshcd_read_device_desc(hba, desc_buf, QUERY_DESC_DEVICE_MAX_SIZE); if (err) { seq_printf(file, "Reading Device Descriptor failed. err = %d\n", err); goto out; } index = desc_buf[DEVICE_DESC_PARAM_PRODUCT_REVISION]; memset(str_desc_buf, 0, QUERY_DESC_STRING_MAX_SIZE + 1); err = ufshcd_read_string_desc(hba, index, str_desc_buf, QUERY_DESC_STRING_MAX_SIZE, ASCII_STD); if (err) { seq_printf(file, "Reading String Descriptor failed. err = %d\n", err); } else { seq_printf(file, "FW revision = %s\n", &str_desc_buf[QUERY_DESC_HDR_SIZE]); } out: pm_runtime_put_sync(hba->dev); return err; } static int ufsdbg_dump_fw_revision_open(struct inode *inode, struct file *file) { return single_open(file, ufsdbg_dump_fw_revision_show, inode->i_private); } static const struct file_operations ufsdbg_dump_fw_revision = { .open = ufsdbg_dump_fw_revision_open, .read = seq_read, .release = single_release, }; static int ufsdbg_dump_serial_show(struct seq_file *file, void *data) { int err = 0; int i, len = 0; u8 index; u8 desc_buf[QUERY_DESC_DEVICE_MAX_SIZE]; u8 str_desc_buf[QUERY_DESC_STRING_MAX_SIZE]; struct ufs_hba *hba = (struct ufs_hba *)file->private; pm_runtime_get_sync(hba->dev); err = ufshcd_read_device_desc(hba, desc_buf, QUERY_DESC_DEVICE_MAX_SIZE); if (err) { seq_printf(file, "Reading Device Descriptor failed. err = %d\n", err); goto out; } index = desc_buf[DEVICE_DESC_PARAM_SN]; memset(str_desc_buf, 0, QUERY_DESC_STRING_MAX_SIZE); err = ufshcd_read_string_desc(hba, index, str_desc_buf, QUERY_DESC_STRING_MAX_SIZE, UTF16_STD); if (err) { seq_printf(file, "Reading String Descriptor failed. err = %d\n", err); goto out; } len = (int)str_desc_buf[QUERY_DESC_LENGTH_OFFSET]; if (len > QUERY_DESC_STRING_MAX_SIZE) len = QUERY_DESC_STRING_MAX_SIZE; seq_puts(file, "Serial = "); for (i = QUERY_DESC_HDR_SIZE; i < len; i++) seq_printf(file, "%02X", str_desc_buf[i]); seq_puts(file, "\n"); out: pm_runtime_put_sync(hba->dev); return err; } static int ufsdbg_dump_serial_open(struct inode *inode, struct file *file) { return single_open(file, ufsdbg_dump_serial_show, inode->i_private); } static const struct file_operations ufsdbg_dump_serial = { .open = ufsdbg_dump_serial_open, .read = seq_read, .release = single_release, }; static int ufsdbg_power_mode_show(struct seq_file *file, void *data) Loading Loading @@ -1214,6 +1378,7 @@ static const struct file_operations ufsdbg_power_mode_desc = { .open = ufsdbg_power_mode_open, .read = seq_read, .write = ufsdbg_power_mode_write, .release = single_release, }; static int ufsdbg_dme_read(void *data, u64 *attr_val, bool peer) Loading Loading @@ -1393,6 +1558,7 @@ static const struct file_operations ufsdbg_req_stats_desc = { .open = ufsdbg_req_stats_open, .read = seq_read, .write = ufsdbg_req_stats_write, .release = single_release, }; Loading Loading @@ -1441,6 +1607,7 @@ static const struct file_operations ufsdbg_reset_controller = { .open = ufsdbg_reset_controller_open, .read = seq_read, .write = ufsdbg_reset_controller_write, .release = single_release, }; static int ufsdbg_clear_err_state(void *data, u64 val) Loading Loading @@ -1649,6 +1816,36 @@ void ufsdbg_add_debugfs(struct ufs_hba *hba) goto err; } hba->debugfs_files.dump_dev_health_desc = debugfs_create_file("dump_device_health_desc", S_IRUSR, hba->debugfs_files.debugfs_root, hba, &ufsdbg_dump_device_health_desc); if (!hba->debugfs_files.dump_dev_health_desc) { dev_err(hba->dev, "%s: NULL dump_device_health_desc file, exiting", __func__); goto err; } hba->debugfs_files.fw_revision = debugfs_create_file("fw_revision", S_IRUSR, hba->debugfs_files.debugfs_root, hba, &ufsdbg_dump_fw_revision); if (!hba->debugfs_files.fw_revision) { dev_err(hba->dev, "%s: NULL fw_revision file, exiting", __func__); goto err; } hba->debugfs_files.serial = debugfs_create_file("serial", S_IRUSR, hba->debugfs_files.debugfs_root, hba, &ufsdbg_dump_serial); if (!hba->debugfs_files.serial) { dev_err(hba->dev, "%s: NULL serial file, exiting", __func__); goto err; } ufsdbg_setup_fault_injection(hba); ufshcd_vops_add_debugfs(hba, hba->debugfs_files.debugfs_root); Loading
drivers/scsi/ufs/ufs-qcom-debugfs.c +3 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ static const struct file_operations ufs_qcom_dbg_testbus_cfg_desc = { .open = ufs_qcom_dbg_testbus_cfg_open, .read = seq_read, .write = ufs_qcom_dbg_testbus_cfg_write, .release = single_release, }; static int ufs_qcom_dbg_testbus_bus_read(void *data, u64 *attr_val) Loading Loading @@ -240,6 +241,7 @@ static int ufs_qcom_dbg_dbg_regs_open(struct inode *inode, static const struct file_operations ufs_qcom_dbg_dbg_regs_desc = { .open = ufs_qcom_dbg_dbg_regs_open, .read = seq_read, .release = single_release, }; static int ufs_qcom_dbg_pm_qos_show(struct seq_file *file, void *data) Loading Loading @@ -273,6 +275,7 @@ static int ufs_qcom_dbg_pm_qos_open(struct inode *inode, static const struct file_operations ufs_qcom_dbg_pm_qos_desc = { .open = ufs_qcom_dbg_pm_qos_open, .read = seq_read, .release = single_release, }; void ufs_qcom_dbg_add_debugfs(struct ufs_hba *hba, struct dentry *root) Loading
drivers/scsi/ufs/ufs-qcom-ice.c +16 −2 Original line number Diff line number Diff line Loading @@ -10,6 +10,11 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* * NOTE: This file has been modified by Sony Mobile Communications Inc. * Modifications are Copyright (c) 2017 Sony Mobile Communications Inc, * and licensed under the license of the file. */ #include <linux/io.h> #include <linux/of.h> Loading @@ -27,6 +32,8 @@ #define UFS_QCOM_ICE_DEFAULT_DBG_PRINT_EN 0 static struct workqueue_struct *ice_workqueue; static void ufs_qcom_ice_dump_regs(struct ufs_qcom_host *qcom_host, int offset, int len, char *prefix) { Loading Loading @@ -224,6 +231,13 @@ int ufs_qcom_ice_init(struct ufs_qcom_host *qcom_host) } qcom_host->dbg_print_en |= UFS_QCOM_ICE_DEFAULT_DBG_PRINT_EN; ice_workqueue = alloc_workqueue("ice-set-key", WQ_MEM_RECLAIM | WQ_HIGHPRI, 0); if (!ice_workqueue) { dev_err(ufs_dev, "%s: workqueue allocation failed.\n", __func__); goto out; } INIT_WORK(&qcom_host->ice_cfg_work, ufs_qcom_ice_cfg_work); out: Loading Loading @@ -284,7 +298,7 @@ int ufs_qcom_ice_req_setup(struct ufs_qcom_host *qcom_host, if (!qcom_host->work_pending) { qcom_host->req_pending = cmd->request; if (!schedule_work( if (!queue_work(ice_workqueue, &qcom_host->ice_cfg_work)) { qcom_host->req_pending = NULL; Loading Loading @@ -404,7 +418,7 @@ int ufs_qcom_ice_cfg_start(struct ufs_qcom_host *qcom_host, if (!qcom_host->work_pending) { qcom_host->req_pending = cmd->request; if (!schedule_work( if (!queue_work(ice_workqueue, &qcom_host->ice_cfg_work)) { qcom_host->req_pending = NULL; Loading