0001
0002
0003
0004
0005
0006 #include "iosm_ipc_coredump.h"
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 int ipc_coredump_collect(struct iosm_devlink *devlink, u8 **data, int entry,
0018 u32 region_size)
0019 {
0020 int ret, bytes_to_read, bytes_read = 0, i = 0;
0021 s32 remaining;
0022 u8 *data_ptr;
0023
0024 data_ptr = vmalloc(region_size);
0025 if (!data_ptr)
0026 return -ENOMEM;
0027
0028 remaining = devlink->cd_file_info[entry].actual_size;
0029 ret = ipc_devlink_send_cmd(devlink, rpsi_cmd_coredump_get, entry);
0030 if (ret) {
0031 dev_err(devlink->dev, "Send coredump_get cmd failed");
0032 goto get_cd_fail;
0033 }
0034 while (remaining > 0) {
0035 bytes_to_read = min(remaining, MAX_DATA_SIZE);
0036 bytes_read = 0;
0037 ret = ipc_imem_sys_devlink_read(devlink, data_ptr + i,
0038 bytes_to_read, &bytes_read);
0039 if (ret) {
0040 dev_err(devlink->dev, "CD data read failed");
0041 goto get_cd_fail;
0042 }
0043 remaining -= bytes_read;
0044 i += bytes_read;
0045 }
0046
0047 *data = data_ptr;
0048
0049 return 0;
0050
0051 get_cd_fail:
0052 vfree(data_ptr);
0053 return ret;
0054 }
0055
0056
0057
0058
0059
0060
0061
0062
0063 int ipc_coredump_get_list(struct iosm_devlink *devlink, u16 cmd)
0064 {
0065 u32 byte_read, num_entries, file_size;
0066 struct iosm_cd_table *cd_table;
0067 u8 size[MAX_SIZE_LEN], i;
0068 char *filename;
0069 int ret;
0070
0071 cd_table = kzalloc(MAX_CD_LIST_SIZE, GFP_KERNEL);
0072 if (!cd_table) {
0073 ret = -ENOMEM;
0074 goto cd_init_fail;
0075 }
0076
0077 ret = ipc_devlink_send_cmd(devlink, cmd, MAX_CD_LIST_SIZE);
0078 if (ret) {
0079 dev_err(devlink->dev, "rpsi_cmd_coredump_start failed");
0080 goto cd_init_fail;
0081 }
0082
0083 ret = ipc_imem_sys_devlink_read(devlink, (u8 *)cd_table,
0084 MAX_CD_LIST_SIZE, &byte_read);
0085 if (ret) {
0086 dev_err(devlink->dev, "Coredump data is invalid");
0087 goto cd_init_fail;
0088 }
0089
0090 if (byte_read != MAX_CD_LIST_SIZE)
0091 goto cd_init_fail;
0092
0093 if (cmd == rpsi_cmd_coredump_start) {
0094 num_entries = le32_to_cpu(cd_table->list.num_entries);
0095 if (num_entries == 0 || num_entries > IOSM_NOF_CD_REGION) {
0096 ret = -EINVAL;
0097 goto cd_init_fail;
0098 }
0099
0100 for (i = 0; i < num_entries; i++) {
0101 file_size = le32_to_cpu(cd_table->list.entry[i].size);
0102 filename = cd_table->list.entry[i].filename;
0103
0104 if (file_size > devlink->cd_file_info[i].default_size) {
0105 ret = -EINVAL;
0106 goto cd_init_fail;
0107 }
0108
0109 devlink->cd_file_info[i].actual_size = file_size;
0110 dev_dbg(devlink->dev, "file: %s actual size %d",
0111 filename, file_size);
0112 devlink_flash_update_status_notify(devlink->devlink_ctx,
0113 filename,
0114 "FILENAME", 0, 0);
0115 snprintf(size, sizeof(size), "%d", file_size);
0116 devlink_flash_update_status_notify(devlink->devlink_ctx,
0117 size, "FILE SIZE",
0118 0, 0);
0119 }
0120 }
0121
0122 cd_init_fail:
0123 kfree(cd_table);
0124 return ret;
0125 }