2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 #include <linux/mutex.h>
48 #include <linux/slab.h>
49 #include <linux/list.h>
50 #include <linux/seq_file.h>
51 #include "adf_accel_devices.h"
54 static DEFINE_MUTEX(qat_cfg_read_lock);
56 static void *qat_dev_cfg_start(struct seq_file *sfile, loff_t *pos)
58 struct adf_cfg_device_data *dev_cfg = sfile->private;
60 mutex_lock(&qat_cfg_read_lock);
61 return seq_list_start(&dev_cfg->sec_list, *pos);
64 static int qat_dev_cfg_show(struct seq_file *sfile, void *v)
66 struct list_head *list;
67 struct adf_cfg_section *sec =
68 list_entry(v, struct adf_cfg_section, list);
70 seq_printf(sfile, "[%s]\n", sec->name);
71 list_for_each(list, &sec->param_head) {
72 struct adf_cfg_key_val *ptr =
73 list_entry(list, struct adf_cfg_key_val, list);
74 seq_printf(sfile, "%s = %s\n", ptr->key, ptr->val);
79 static void *qat_dev_cfg_next(struct seq_file *sfile, void *v, loff_t *pos)
81 struct adf_cfg_device_data *dev_cfg = sfile->private;
83 return seq_list_next(v, &dev_cfg->sec_list, pos);
86 static void qat_dev_cfg_stop(struct seq_file *sfile, void *v)
88 mutex_unlock(&qat_cfg_read_lock);
91 static const struct seq_operations qat_dev_cfg_sops = {
92 .start = qat_dev_cfg_start,
93 .next = qat_dev_cfg_next,
94 .stop = qat_dev_cfg_stop,
95 .show = qat_dev_cfg_show
98 static int qat_dev_cfg_open(struct inode *inode, struct file *file)
100 int ret = seq_open(file, &qat_dev_cfg_sops);
103 struct seq_file *seq_f = file->private_data;
105 seq_f->private = inode->i_private;
110 static const struct file_operations qat_dev_cfg_fops = {
111 .open = qat_dev_cfg_open,
114 .release = seq_release
118 * adf_cfg_dev_add() - Create an acceleration device configuration table.
119 * @accel_dev: Pointer to acceleration device.
121 * Function creates a configuration table for the given acceleration device.
122 * The table stores device specific config values.
123 * To be used by QAT device specific drivers.
125 * Return: 0 on success, error code othewise.
127 int adf_cfg_dev_add(struct adf_accel_dev *accel_dev)
129 struct adf_cfg_device_data *dev_cfg_data;
131 dev_cfg_data = kzalloc(sizeof(*dev_cfg_data), GFP_KERNEL);
134 INIT_LIST_HEAD(&dev_cfg_data->sec_list);
135 init_rwsem(&dev_cfg_data->lock);
136 accel_dev->cfg = dev_cfg_data;
138 /* accel_dev->debugfs_dir should always be non-NULL here */
139 dev_cfg_data->debug = debugfs_create_file("dev_cfg", S_IRUSR,
140 accel_dev->debugfs_dir,
143 if (!dev_cfg_data->debug) {
144 pr_err("QAT: Failed to create qat cfg debugfs entry.\n");
146 accel_dev->cfg = NULL;
151 EXPORT_SYMBOL_GPL(adf_cfg_dev_add);
153 static void adf_cfg_section_del_all(struct list_head *head);
155 void adf_cfg_del_all(struct adf_accel_dev *accel_dev)
157 struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
159 down_write(&dev_cfg_data->lock);
160 adf_cfg_section_del_all(&dev_cfg_data->sec_list);
161 up_write(&dev_cfg_data->lock);
165 * adf_cfg_dev_remove() - Clears acceleration device configuration table.
166 * @accel_dev: Pointer to acceleration device.
168 * Function removes configuration table from the given acceleration device
169 * and frees all allocated memory.
170 * To be used by QAT device specific drivers.
174 void adf_cfg_dev_remove(struct adf_accel_dev *accel_dev)
176 struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
178 down_write(&dev_cfg_data->lock);
179 adf_cfg_section_del_all(&dev_cfg_data->sec_list);
180 up_write(&dev_cfg_data->lock);
181 debugfs_remove(dev_cfg_data->debug);
183 accel_dev->cfg = NULL;
185 EXPORT_SYMBOL_GPL(adf_cfg_dev_remove);
187 static void adf_cfg_keyval_add(struct adf_cfg_key_val *new,
188 struct adf_cfg_section *sec)
190 list_add_tail(&new->list, &sec->param_head);
193 static void adf_cfg_keyval_del_all(struct list_head *head)
195 struct list_head *list_ptr, *tmp;
197 list_for_each_prev_safe(list_ptr, tmp, head) {
198 struct adf_cfg_key_val *ptr =
199 list_entry(list_ptr, struct adf_cfg_key_val, list);
205 static void adf_cfg_section_del_all(struct list_head *head)
207 struct adf_cfg_section *ptr;
208 struct list_head *list, *tmp;
210 list_for_each_prev_safe(list, tmp, head) {
211 ptr = list_entry(list, struct adf_cfg_section, list);
212 adf_cfg_keyval_del_all(&ptr->param_head);
218 static struct adf_cfg_key_val *adf_cfg_key_value_find(struct adf_cfg_section *s,
221 struct list_head *list;
223 list_for_each(list, &s->param_head) {
224 struct adf_cfg_key_val *ptr =
225 list_entry(list, struct adf_cfg_key_val, list);
226 if (!strcmp(ptr->key, key))
232 static struct adf_cfg_section *adf_cfg_sec_find(struct adf_accel_dev *accel_dev,
233 const char *sec_name)
235 struct adf_cfg_device_data *cfg = accel_dev->cfg;
236 struct list_head *list;
238 list_for_each(list, &cfg->sec_list) {
239 struct adf_cfg_section *ptr =
240 list_entry(list, struct adf_cfg_section, list);
241 if (!strcmp(ptr->name, sec_name))
247 static int adf_cfg_key_val_get(struct adf_accel_dev *accel_dev,
248 const char *sec_name,
249 const char *key_name,
252 struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, sec_name);
253 struct adf_cfg_key_val *keyval = NULL;
256 keyval = adf_cfg_key_value_find(sec, key_name);
258 memcpy(val, keyval->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
265 * adf_cfg_add_key_value_param() - Add key-value config entry to config table.
266 * @accel_dev: Pointer to acceleration device.
267 * @section_name: Name of the section where the param will be added
268 * @key: The key string
269 * @val: Value pain for the given @key
270 * @type: Type - string, int or address
272 * Function adds configuration key - value entry in the appropriate section
273 * in the given acceleration device
274 * To be used by QAT device specific drivers.
276 * Return: 0 on success, error code othewise.
278 int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev,
279 const char *section_name,
280 const char *key, const void *val,
281 enum adf_cfg_val_type type)
283 struct adf_cfg_device_data *cfg = accel_dev->cfg;
284 struct adf_cfg_key_val *key_val;
285 struct adf_cfg_section *section = adf_cfg_sec_find(accel_dev,
290 key_val = kzalloc(sizeof(*key_val), GFP_KERNEL);
294 INIT_LIST_HEAD(&key_val->list);
295 strlcpy(key_val->key, key, sizeof(key_val->key));
297 if (type == ADF_DEC) {
298 snprintf(key_val->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,
299 "%ld", (*((long *)val)));
300 } else if (type == ADF_STR) {
301 strlcpy(key_val->val, (char *)val, sizeof(key_val->val));
302 } else if (type == ADF_HEX) {
303 snprintf(key_val->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,
304 "0x%lx", (unsigned long)val);
306 pr_err("QAT: Unknown type given.\n");
310 key_val->type = type;
311 down_write(&cfg->lock);
312 adf_cfg_keyval_add(key_val, section);
313 up_write(&cfg->lock);
316 EXPORT_SYMBOL_GPL(adf_cfg_add_key_value_param);
319 * adf_cfg_section_add() - Add config section entry to config table.
320 * @accel_dev: Pointer to acceleration device.
321 * @name: Name of the section
323 * Function adds configuration section where key - value entries
325 * To be used by QAT device specific drivers.
327 * Return: 0 on success, error code othewise.
329 int adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name)
331 struct adf_cfg_device_data *cfg = accel_dev->cfg;
332 struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name);
337 sec = kzalloc(sizeof(*sec), GFP_KERNEL);
341 strlcpy(sec->name, name, sizeof(sec->name));
342 INIT_LIST_HEAD(&sec->param_head);
343 down_write(&cfg->lock);
344 list_add_tail(&sec->list, &cfg->sec_list);
345 up_write(&cfg->lock);
348 EXPORT_SYMBOL_GPL(adf_cfg_section_add);
350 int adf_cfg_get_param_value(struct adf_accel_dev *accel_dev,
351 const char *section, const char *name,
354 struct adf_cfg_device_data *cfg = accel_dev->cfg;
357 down_read(&cfg->lock);
358 ret = adf_cfg_key_val_get(accel_dev, section, name, value);