iosm_ipc_coredump.c (3091B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2020-2021 Intel Corporation. 4 */ 5 6#include "iosm_ipc_coredump.h" 7 8/** 9 * ipc_coredump_collect - To collect coredump 10 * @devlink: Pointer to devlink instance. 11 * @data: Pointer to snapshot 12 * @entry: ID of requested snapshot 13 * @region_size: Region size 14 * 15 * Returns: 0 on success, error on failure 16 */ 17int ipc_coredump_collect(struct iosm_devlink *devlink, u8 **data, int entry, 18 u32 region_size) 19{ 20 int ret, bytes_to_read, bytes_read = 0, i = 0; 21 s32 remaining; 22 u8 *data_ptr; 23 24 data_ptr = vmalloc(region_size); 25 if (!data_ptr) 26 return -ENOMEM; 27 28 remaining = devlink->cd_file_info[entry].actual_size; 29 ret = ipc_devlink_send_cmd(devlink, rpsi_cmd_coredump_get, entry); 30 if (ret) { 31 dev_err(devlink->dev, "Send coredump_get cmd failed"); 32 goto get_cd_fail; 33 } 34 while (remaining > 0) { 35 bytes_to_read = min(remaining, MAX_DATA_SIZE); 36 bytes_read = 0; 37 ret = ipc_imem_sys_devlink_read(devlink, data_ptr + i, 38 bytes_to_read, &bytes_read); 39 if (ret) { 40 dev_err(devlink->dev, "CD data read failed"); 41 goto get_cd_fail; 42 } 43 remaining -= bytes_read; 44 i += bytes_read; 45 } 46 47 *data = data_ptr; 48 49 return 0; 50 51get_cd_fail: 52 vfree(data_ptr); 53 return ret; 54} 55 56/** 57 * ipc_coredump_get_list - Get coredump list from modem 58 * @devlink: Pointer to devlink instance. 59 * @cmd: RPSI command to be sent 60 * 61 * Returns: 0 on success, error on failure 62 */ 63int ipc_coredump_get_list(struct iosm_devlink *devlink, u16 cmd) 64{ 65 u32 byte_read, num_entries, file_size; 66 struct iosm_cd_table *cd_table; 67 u8 size[MAX_SIZE_LEN], i; 68 char *filename; 69 int ret; 70 71 cd_table = kzalloc(MAX_CD_LIST_SIZE, GFP_KERNEL); 72 if (!cd_table) { 73 ret = -ENOMEM; 74 goto cd_init_fail; 75 } 76 77 ret = ipc_devlink_send_cmd(devlink, cmd, MAX_CD_LIST_SIZE); 78 if (ret) { 79 dev_err(devlink->dev, "rpsi_cmd_coredump_start failed"); 80 goto cd_init_fail; 81 } 82 83 ret = ipc_imem_sys_devlink_read(devlink, (u8 *)cd_table, 84 MAX_CD_LIST_SIZE, &byte_read); 85 if (ret) { 86 dev_err(devlink->dev, "Coredump data is invalid"); 87 goto cd_init_fail; 88 } 89 90 if (byte_read != MAX_CD_LIST_SIZE) 91 goto cd_init_fail; 92 93 if (cmd == rpsi_cmd_coredump_start) { 94 num_entries = le32_to_cpu(cd_table->list.num_entries); 95 if (num_entries == 0 || num_entries > IOSM_NOF_CD_REGION) { 96 ret = -EINVAL; 97 goto cd_init_fail; 98 } 99 100 for (i = 0; i < num_entries; i++) { 101 file_size = le32_to_cpu(cd_table->list.entry[i].size); 102 filename = cd_table->list.entry[i].filename; 103 104 if (file_size > devlink->cd_file_info[i].default_size) { 105 ret = -EINVAL; 106 goto cd_init_fail; 107 } 108 109 devlink->cd_file_info[i].actual_size = file_size; 110 dev_dbg(devlink->dev, "file: %s actual size %d", 111 filename, file_size); 112 devlink_flash_update_status_notify(devlink->devlink_ctx, 113 filename, 114 "FILENAME", 0, 0); 115 snprintf(size, sizeof(size), "%d", file_size); 116 devlink_flash_update_status_notify(devlink->devlink_ctx, 117 size, "FILE SIZE", 118 0, 0); 119 } 120 } 121 122cd_init_fail: 123 kfree(cd_table); 124 return ret; 125}