Linux Audio

Check our new training course

Yocto distribution development and maintenance

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