]> Git Repo - linux.git/blob - drivers/net/wwan/iosm/iosm_ipc_coredump.c
Merge tag 'cxl-for-6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl
[linux.git] / drivers / net / wwan / iosm / iosm_ipc_coredump.c
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  */
17 int 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
51 get_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  */
63 int 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
122 cd_init_fail:
123         kfree(cd_table);
124         return ret;
125 }
This page took 0.042088 seconds and 4 git commands to generate.