1266b0663SKrzysztof Zdziarski /* SPDX-License-Identifier: BSD-3-Clause */
2266b0663SKrzysztof Zdziarski /* Copyright(c) 2007-2022 Intel Corporation */
3266b0663SKrzysztof Zdziarski
4266b0663SKrzysztof Zdziarski #include "qat_freebsd.h"
5266b0663SKrzysztof Zdziarski #include "adf_cfg.h"
6266b0663SKrzysztof Zdziarski #include "adf_common_drv.h"
7266b0663SKrzysztof Zdziarski #include "adf_accel_devices.h"
8266b0663SKrzysztof Zdziarski #include "icp_qat_uclo.h"
9266b0663SKrzysztof Zdziarski #include "icp_qat_fw.h"
10266b0663SKrzysztof Zdziarski #include "icp_qat_fw_init_admin.h"
11266b0663SKrzysztof Zdziarski #include "adf_cfg_strings.h"
12266b0663SKrzysztof Zdziarski #include "adf_uio_control.h"
13266b0663SKrzysztof Zdziarski #include "adf_uio_cleanup.h"
14266b0663SKrzysztof Zdziarski #include "adf_uio.h"
15266b0663SKrzysztof Zdziarski #include "adf_transport_access_macros.h"
16266b0663SKrzysztof Zdziarski #include "adf_transport_internal.h"
17266b0663SKrzysztof Zdziarski
18266b0663SKrzysztof Zdziarski #define ADF_DEV_PROCESSES_NAME "qat_dev_processes"
19266b0663SKrzysztof Zdziarski #define ADF_DEV_STATE_NAME "qat_dev_state"
20266b0663SKrzysztof Zdziarski
21266b0663SKrzysztof Zdziarski #define ADF_STATE_CALLOUT_TIME 10
22266b0663SKrzysztof Zdziarski
23*22cf89c9SPiotr Kasierski static const char *mtx_name = "state_mtx";
24*22cf89c9SPiotr Kasierski static const char *mtx_callout_name = "callout_mtx";
25266b0663SKrzysztof Zdziarski
26266b0663SKrzysztof Zdziarski static d_open_t adf_processes_open;
27266b0663SKrzysztof Zdziarski static void adf_processes_release(void *data);
28266b0663SKrzysztof Zdziarski static d_read_t adf_processes_read;
29266b0663SKrzysztof Zdziarski static d_write_t adf_processes_write;
30266b0663SKrzysztof Zdziarski
31266b0663SKrzysztof Zdziarski static d_open_t adf_state_open;
32266b0663SKrzysztof Zdziarski static void adf_state_release(void *data);
33266b0663SKrzysztof Zdziarski static d_read_t adf_state_read;
34266b0663SKrzysztof Zdziarski static int adf_state_kqfilter(struct cdev *dev, struct knote *kn);
35266b0663SKrzysztof Zdziarski static int adf_state_kqread_event(struct knote *kn, long hint);
36266b0663SKrzysztof Zdziarski static void adf_state_kqread_detach(struct knote *kn);
37266b0663SKrzysztof Zdziarski
38266b0663SKrzysztof Zdziarski static struct callout callout;
39266b0663SKrzysztof Zdziarski static struct mtx mtx;
40*22cf89c9SPiotr Kasierski static struct mtx callout_mtx;
41266b0663SKrzysztof Zdziarski static struct service_hndl adf_state_hndl;
42266b0663SKrzysztof Zdziarski
43266b0663SKrzysztof Zdziarski struct entry_proc_events {
44266b0663SKrzysztof Zdziarski struct adf_state_priv_data *proc_events;
45266b0663SKrzysztof Zdziarski
46266b0663SKrzysztof Zdziarski SLIST_ENTRY(entry_proc_events) entries_proc_events;
47266b0663SKrzysztof Zdziarski };
48266b0663SKrzysztof Zdziarski
49266b0663SKrzysztof Zdziarski struct entry_state {
50266b0663SKrzysztof Zdziarski struct adf_state state;
51266b0663SKrzysztof Zdziarski
52266b0663SKrzysztof Zdziarski STAILQ_ENTRY(entry_state) entries_state;
53266b0663SKrzysztof Zdziarski };
54266b0663SKrzysztof Zdziarski
55266b0663SKrzysztof Zdziarski SLIST_HEAD(proc_events_head, entry_proc_events);
56266b0663SKrzysztof Zdziarski STAILQ_HEAD(state_head, entry_state);
57266b0663SKrzysztof Zdziarski
58266b0663SKrzysztof Zdziarski static struct proc_events_head proc_events_head;
59266b0663SKrzysztof Zdziarski
60266b0663SKrzysztof Zdziarski struct adf_processes_priv_data {
61266b0663SKrzysztof Zdziarski char name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES];
62266b0663SKrzysztof Zdziarski int read_flag;
63266b0663SKrzysztof Zdziarski struct list_head list;
64266b0663SKrzysztof Zdziarski };
65266b0663SKrzysztof Zdziarski
66266b0663SKrzysztof Zdziarski struct adf_state_priv_data {
67266b0663SKrzysztof Zdziarski struct cdev *cdev;
68266b0663SKrzysztof Zdziarski struct selinfo rsel;
69266b0663SKrzysztof Zdziarski struct state_head state_head;
70266b0663SKrzysztof Zdziarski };
71266b0663SKrzysztof Zdziarski
72266b0663SKrzysztof Zdziarski static struct cdevsw adf_processes_cdevsw = {
73266b0663SKrzysztof Zdziarski .d_version = D_VERSION,
74266b0663SKrzysztof Zdziarski .d_open = adf_processes_open,
75266b0663SKrzysztof Zdziarski .d_read = adf_processes_read,
76266b0663SKrzysztof Zdziarski .d_write = adf_processes_write,
77266b0663SKrzysztof Zdziarski .d_name = ADF_DEV_PROCESSES_NAME,
78266b0663SKrzysztof Zdziarski };
79266b0663SKrzysztof Zdziarski
80266b0663SKrzysztof Zdziarski static struct cdevsw adf_state_cdevsw = {
81266b0663SKrzysztof Zdziarski .d_version = D_VERSION,
82266b0663SKrzysztof Zdziarski .d_open = adf_state_open,
83266b0663SKrzysztof Zdziarski .d_read = adf_state_read,
84266b0663SKrzysztof Zdziarski .d_kqfilter = adf_state_kqfilter,
85266b0663SKrzysztof Zdziarski .d_name = ADF_DEV_STATE_NAME,
86266b0663SKrzysztof Zdziarski };
87266b0663SKrzysztof Zdziarski
88266b0663SKrzysztof Zdziarski static struct filterops adf_state_read_filterops = {
89266b0663SKrzysztof Zdziarski .f_isfd = 1,
90266b0663SKrzysztof Zdziarski .f_attach = NULL,
91266b0663SKrzysztof Zdziarski .f_detach = adf_state_kqread_detach,
92266b0663SKrzysztof Zdziarski .f_event = adf_state_kqread_event,
93266b0663SKrzysztof Zdziarski };
94266b0663SKrzysztof Zdziarski
95266b0663SKrzysztof Zdziarski static struct cdev *adf_processes_dev;
96266b0663SKrzysztof Zdziarski static struct cdev *adf_state_dev;
97266b0663SKrzysztof Zdziarski
98266b0663SKrzysztof Zdziarski static LINUX_LIST_HEAD(processes_list);
99266b0663SKrzysztof Zdziarski
100266b0663SKrzysztof Zdziarski struct sx processes_list_sema;
101266b0663SKrzysztof Zdziarski SX_SYSINIT(processes_list_sema, &processes_list_sema, "adf proc list");
102266b0663SKrzysztof Zdziarski
103266b0663SKrzysztof Zdziarski static void
adf_chr_drv_destroy(void)104266b0663SKrzysztof Zdziarski adf_chr_drv_destroy(void)
105266b0663SKrzysztof Zdziarski {
106266b0663SKrzysztof Zdziarski destroy_dev(adf_processes_dev);
107266b0663SKrzysztof Zdziarski }
108266b0663SKrzysztof Zdziarski
109266b0663SKrzysztof Zdziarski static int
adf_chr_drv_create(void)110266b0663SKrzysztof Zdziarski adf_chr_drv_create(void)
111266b0663SKrzysztof Zdziarski {
112266b0663SKrzysztof Zdziarski
113266b0663SKrzysztof Zdziarski adf_processes_dev = make_dev(&adf_processes_cdevsw,
114266b0663SKrzysztof Zdziarski 0,
115266b0663SKrzysztof Zdziarski UID_ROOT,
116266b0663SKrzysztof Zdziarski GID_WHEEL,
117266b0663SKrzysztof Zdziarski 0600,
118266b0663SKrzysztof Zdziarski ADF_DEV_PROCESSES_NAME);
119266b0663SKrzysztof Zdziarski if (adf_processes_dev == NULL) {
120266b0663SKrzysztof Zdziarski printf("QAT: failed to create device\n");
121266b0663SKrzysztof Zdziarski goto err_cdev_del;
122266b0663SKrzysztof Zdziarski }
123266b0663SKrzysztof Zdziarski return 0;
124266b0663SKrzysztof Zdziarski err_cdev_del:
125266b0663SKrzysztof Zdziarski return EFAULT;
126266b0663SKrzysztof Zdziarski }
127266b0663SKrzysztof Zdziarski
128266b0663SKrzysztof Zdziarski static int
adf_processes_open(struct cdev * dev,int oflags,int devtype,struct thread * td)129266b0663SKrzysztof Zdziarski adf_processes_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
130266b0663SKrzysztof Zdziarski {
131266b0663SKrzysztof Zdziarski int i = 0, devices = 0;
132266b0663SKrzysztof Zdziarski struct adf_accel_dev *accel_dev = NULL;
133266b0663SKrzysztof Zdziarski struct adf_processes_priv_data *prv_data = NULL;
134266b0663SKrzysztof Zdziarski int error = 0;
135266b0663SKrzysztof Zdziarski
136266b0663SKrzysztof Zdziarski for (i = 0; i < ADF_MAX_DEVICES; i++) {
137266b0663SKrzysztof Zdziarski accel_dev = adf_devmgr_get_dev_by_id(i);
138266b0663SKrzysztof Zdziarski if (!accel_dev)
139266b0663SKrzysztof Zdziarski continue;
140266b0663SKrzysztof Zdziarski if (!adf_dev_started(accel_dev))
141266b0663SKrzysztof Zdziarski continue;
142266b0663SKrzysztof Zdziarski devices++;
143266b0663SKrzysztof Zdziarski }
144266b0663SKrzysztof Zdziarski if (!devices) {
145266b0663SKrzysztof Zdziarski printf("QAT: No active devices found.\n");
146266b0663SKrzysztof Zdziarski return ENXIO;
147266b0663SKrzysztof Zdziarski }
148266b0663SKrzysztof Zdziarski prv_data = malloc(sizeof(*prv_data), M_QAT, M_WAITOK | M_ZERO);
149266b0663SKrzysztof Zdziarski INIT_LIST_HEAD(&prv_data->list);
150266b0663SKrzysztof Zdziarski error = devfs_set_cdevpriv(prv_data, adf_processes_release);
151266b0663SKrzysztof Zdziarski if (error) {
152266b0663SKrzysztof Zdziarski free(prv_data, M_QAT);
153266b0663SKrzysztof Zdziarski return error;
154266b0663SKrzysztof Zdziarski }
155266b0663SKrzysztof Zdziarski
156266b0663SKrzysztof Zdziarski return 0;
157266b0663SKrzysztof Zdziarski }
158266b0663SKrzysztof Zdziarski
159266b0663SKrzysztof Zdziarski static int
adf_get_first_started_dev(void)160266b0663SKrzysztof Zdziarski adf_get_first_started_dev(void)
161266b0663SKrzysztof Zdziarski {
162266b0663SKrzysztof Zdziarski int i = 0;
163266b0663SKrzysztof Zdziarski struct adf_accel_dev *accel_dev = NULL;
164266b0663SKrzysztof Zdziarski
165266b0663SKrzysztof Zdziarski for (i = 0; i < ADF_MAX_DEVICES; i++) {
166266b0663SKrzysztof Zdziarski accel_dev = adf_devmgr_get_dev_by_id(i);
167266b0663SKrzysztof Zdziarski if (!accel_dev)
168266b0663SKrzysztof Zdziarski continue;
169266b0663SKrzysztof Zdziarski if (adf_dev_started(accel_dev))
170266b0663SKrzysztof Zdziarski return i;
171266b0663SKrzysztof Zdziarski }
172266b0663SKrzysztof Zdziarski
173266b0663SKrzysztof Zdziarski return -1;
174266b0663SKrzysztof Zdziarski }
175266b0663SKrzysztof Zdziarski
176266b0663SKrzysztof Zdziarski static int
adf_processes_write(struct cdev * dev,struct uio * uio,int ioflag)177266b0663SKrzysztof Zdziarski adf_processes_write(struct cdev *dev, struct uio *uio, int ioflag)
178266b0663SKrzysztof Zdziarski {
179266b0663SKrzysztof Zdziarski struct adf_processes_priv_data *prv_data = NULL;
180266b0663SKrzysztof Zdziarski struct adf_processes_priv_data *pdata = NULL;
181266b0663SKrzysztof Zdziarski int dev_num = 0, pr_num = 0;
182266b0663SKrzysztof Zdziarski struct list_head *lpos = NULL;
183266b0663SKrzysztof Zdziarski char usr_name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES] = { 0 };
184266b0663SKrzysztof Zdziarski struct adf_accel_dev *accel_dev = NULL;
185266b0663SKrzysztof Zdziarski struct adf_cfg_section *section_ptr = NULL;
186266b0663SKrzysztof Zdziarski bool pr_name_available = 1;
187266b0663SKrzysztof Zdziarski uint32_t num_accel_devs = 0;
188266b0663SKrzysztof Zdziarski int error = 0;
189266b0663SKrzysztof Zdziarski ssize_t count;
190266b0663SKrzysztof Zdziarski int dev_id;
191266b0663SKrzysztof Zdziarski
192266b0663SKrzysztof Zdziarski error = devfs_get_cdevpriv((void **)&prv_data);
193266b0663SKrzysztof Zdziarski if (error) {
194266b0663SKrzysztof Zdziarski printf("QAT: invalid file descriptor\n");
195266b0663SKrzysztof Zdziarski return error;
196266b0663SKrzysztof Zdziarski }
197266b0663SKrzysztof Zdziarski
198266b0663SKrzysztof Zdziarski if (prv_data->read_flag == 1) {
199266b0663SKrzysztof Zdziarski printf("QAT: can only write once\n");
200266b0663SKrzysztof Zdziarski return EBADF;
201266b0663SKrzysztof Zdziarski }
202266b0663SKrzysztof Zdziarski count = uio->uio_resid;
203266b0663SKrzysztof Zdziarski if ((count <= 0) || (count > ADF_CFG_MAX_SECTION_LEN_IN_BYTES)) {
204266b0663SKrzysztof Zdziarski printf("QAT: wrong size %d\n", (int)count);
205266b0663SKrzysztof Zdziarski return EIO;
206266b0663SKrzysztof Zdziarski }
207266b0663SKrzysztof Zdziarski
208266b0663SKrzysztof Zdziarski error = uiomove(usr_name, count, uio);
209266b0663SKrzysztof Zdziarski if (error) {
210266b0663SKrzysztof Zdziarski printf("QAT: can't copy data\n");
211266b0663SKrzysztof Zdziarski return error;
212266b0663SKrzysztof Zdziarski }
213266b0663SKrzysztof Zdziarski
214266b0663SKrzysztof Zdziarski /* Lock other processes and try to find out the process name */
215266b0663SKrzysztof Zdziarski if (sx_xlock_sig(&processes_list_sema)) {
216266b0663SKrzysztof Zdziarski printf("QAT: can't aquire process info lock\n");
217266b0663SKrzysztof Zdziarski return EBADF;
218266b0663SKrzysztof Zdziarski }
219266b0663SKrzysztof Zdziarski
220266b0663SKrzysztof Zdziarski dev_id = adf_get_first_started_dev();
221266b0663SKrzysztof Zdziarski if (-1 == dev_id) {
222266b0663SKrzysztof Zdziarski pr_err("QAT: could not find started device\n");
223266b0663SKrzysztof Zdziarski sx_xunlock(&processes_list_sema);
224266b0663SKrzysztof Zdziarski return -EIO;
225266b0663SKrzysztof Zdziarski }
226266b0663SKrzysztof Zdziarski
227266b0663SKrzysztof Zdziarski accel_dev = adf_devmgr_get_dev_by_id(dev_id);
228266b0663SKrzysztof Zdziarski if (!accel_dev) {
229266b0663SKrzysztof Zdziarski pr_err("QAT: could not find started device\n");
230266b0663SKrzysztof Zdziarski sx_xunlock(&processes_list_sema);
231266b0663SKrzysztof Zdziarski return -EIO;
232266b0663SKrzysztof Zdziarski }
233266b0663SKrzysztof Zdziarski
234266b0663SKrzysztof Zdziarski /* If there is nothing there then take the first name and return */
235266b0663SKrzysztof Zdziarski if (list_empty(&processes_list)) {
236266b0663SKrzysztof Zdziarski snprintf(prv_data->name,
237266b0663SKrzysztof Zdziarski ADF_CFG_MAX_SECTION_LEN_IN_BYTES,
238266b0663SKrzysztof Zdziarski "%s" ADF_INTERNAL_USERSPACE_SEC_SUFF "%d",
239266b0663SKrzysztof Zdziarski usr_name,
240266b0663SKrzysztof Zdziarski 0);
241266b0663SKrzysztof Zdziarski list_add(&prv_data->list, &processes_list);
242266b0663SKrzysztof Zdziarski sx_xunlock(&processes_list_sema);
243266b0663SKrzysztof Zdziarski prv_data->read_flag = 1;
244266b0663SKrzysztof Zdziarski return 0;
245266b0663SKrzysztof Zdziarski }
246266b0663SKrzysztof Zdziarski
247266b0663SKrzysztof Zdziarski /* If there are processes running then search for a first free name */
248266b0663SKrzysztof Zdziarski adf_devmgr_get_num_dev(&num_accel_devs);
249266b0663SKrzysztof Zdziarski for (dev_num = 0; dev_num < num_accel_devs; dev_num++) {
250266b0663SKrzysztof Zdziarski accel_dev = adf_devmgr_get_dev_by_id(dev_num);
251266b0663SKrzysztof Zdziarski if (!accel_dev)
252266b0663SKrzysztof Zdziarski continue;
253266b0663SKrzysztof Zdziarski
254266b0663SKrzysztof Zdziarski if (!adf_dev_started(accel_dev))
255266b0663SKrzysztof Zdziarski continue; /* to next device */
256266b0663SKrzysztof Zdziarski
257266b0663SKrzysztof Zdziarski for (pr_num = 0; pr_num < GET_MAX_PROCESSES(accel_dev);
258266b0663SKrzysztof Zdziarski pr_num++) {
259266b0663SKrzysztof Zdziarski snprintf(prv_data->name,
260266b0663SKrzysztof Zdziarski ADF_CFG_MAX_SECTION_LEN_IN_BYTES,
261266b0663SKrzysztof Zdziarski "%s" ADF_INTERNAL_USERSPACE_SEC_SUFF "%d",
262266b0663SKrzysztof Zdziarski usr_name,
263266b0663SKrzysztof Zdziarski pr_num);
264266b0663SKrzysztof Zdziarski pr_name_available = 1;
265266b0663SKrzysztof Zdziarski /* Figure out if section exists in the config table */
266266b0663SKrzysztof Zdziarski section_ptr =
267266b0663SKrzysztof Zdziarski adf_cfg_sec_find(accel_dev, prv_data->name);
268266b0663SKrzysztof Zdziarski if (NULL == section_ptr) {
269266b0663SKrzysztof Zdziarski /* This section name doesn't exist */
270266b0663SKrzysztof Zdziarski pr_name_available = 0;
271266b0663SKrzysztof Zdziarski /* As process_num enumerates from 0, once we get
272266b0663SKrzysztof Zdziarski * to one which doesn't exist no further ones
273266b0663SKrzysztof Zdziarski * will exist. On to next device
274266b0663SKrzysztof Zdziarski */
275266b0663SKrzysztof Zdziarski break;
276266b0663SKrzysztof Zdziarski }
277266b0663SKrzysztof Zdziarski /* Figure out if it's been taken already */
278266b0663SKrzysztof Zdziarski list_for_each(lpos, &processes_list)
279266b0663SKrzysztof Zdziarski {
280266b0663SKrzysztof Zdziarski pdata =
281266b0663SKrzysztof Zdziarski list_entry(lpos,
282266b0663SKrzysztof Zdziarski struct adf_processes_priv_data,
283266b0663SKrzysztof Zdziarski list);
284266b0663SKrzysztof Zdziarski if (!strncmp(
285266b0663SKrzysztof Zdziarski pdata->name,
286266b0663SKrzysztof Zdziarski prv_data->name,
287266b0663SKrzysztof Zdziarski ADF_CFG_MAX_SECTION_LEN_IN_BYTES)) {
288266b0663SKrzysztof Zdziarski pr_name_available = 0;
289266b0663SKrzysztof Zdziarski break;
290266b0663SKrzysztof Zdziarski }
291266b0663SKrzysztof Zdziarski }
292266b0663SKrzysztof Zdziarski if (pr_name_available)
293266b0663SKrzysztof Zdziarski break;
294266b0663SKrzysztof Zdziarski }
295266b0663SKrzysztof Zdziarski if (pr_name_available)
296266b0663SKrzysztof Zdziarski break;
297266b0663SKrzysztof Zdziarski }
298266b0663SKrzysztof Zdziarski /*
299266b0663SKrzysztof Zdziarski * If we have a valid name that is not on
300266b0663SKrzysztof Zdziarski * the list take it and add to the list
301266b0663SKrzysztof Zdziarski */
302266b0663SKrzysztof Zdziarski if (pr_name_available) {
303266b0663SKrzysztof Zdziarski list_add(&prv_data->list, &processes_list);
304266b0663SKrzysztof Zdziarski sx_xunlock(&processes_list_sema);
305266b0663SKrzysztof Zdziarski prv_data->read_flag = 1;
306266b0663SKrzysztof Zdziarski return 0;
307266b0663SKrzysztof Zdziarski }
308266b0663SKrzysztof Zdziarski /* If not then the process needs to wait */
309266b0663SKrzysztof Zdziarski sx_xunlock(&processes_list_sema);
310266b0663SKrzysztof Zdziarski explicit_bzero(prv_data->name, ADF_CFG_MAX_SECTION_LEN_IN_BYTES);
311266b0663SKrzysztof Zdziarski prv_data->read_flag = 0;
312266b0663SKrzysztof Zdziarski return 1;
313266b0663SKrzysztof Zdziarski }
314266b0663SKrzysztof Zdziarski
315266b0663SKrzysztof Zdziarski static int
adf_processes_read(struct cdev * dev,struct uio * uio,int ioflag)316266b0663SKrzysztof Zdziarski adf_processes_read(struct cdev *dev, struct uio *uio, int ioflag)
317266b0663SKrzysztof Zdziarski {
318266b0663SKrzysztof Zdziarski struct adf_processes_priv_data *prv_data = NULL;
319266b0663SKrzysztof Zdziarski int error = 0;
320266b0663SKrzysztof Zdziarski
321266b0663SKrzysztof Zdziarski error = devfs_get_cdevpriv((void **)&prv_data);
322266b0663SKrzysztof Zdziarski if (error) {
323266b0663SKrzysztof Zdziarski printf("QAT: invalid file descriptor\n");
324266b0663SKrzysztof Zdziarski return error;
325266b0663SKrzysztof Zdziarski }
326266b0663SKrzysztof Zdziarski
327266b0663SKrzysztof Zdziarski /*
328266b0663SKrzysztof Zdziarski * If there is a name that the process can use then give it
329266b0663SKrzysztof Zdziarski * to the proocess.
330266b0663SKrzysztof Zdziarski */
331266b0663SKrzysztof Zdziarski if (prv_data->read_flag) {
332266b0663SKrzysztof Zdziarski error = uiomove(prv_data->name,
333266b0663SKrzysztof Zdziarski strnlen(prv_data->name,
334266b0663SKrzysztof Zdziarski ADF_CFG_MAX_SECTION_LEN_IN_BYTES),
335266b0663SKrzysztof Zdziarski uio);
336266b0663SKrzysztof Zdziarski if (error) {
337266b0663SKrzysztof Zdziarski printf("QAT: failed to copy data to user\n");
338266b0663SKrzysztof Zdziarski return error;
339266b0663SKrzysztof Zdziarski }
340266b0663SKrzysztof Zdziarski return 0;
341266b0663SKrzysztof Zdziarski }
342266b0663SKrzysztof Zdziarski
343266b0663SKrzysztof Zdziarski return EIO;
344266b0663SKrzysztof Zdziarski }
345266b0663SKrzysztof Zdziarski
346266b0663SKrzysztof Zdziarski static void
adf_processes_release(void * data)347266b0663SKrzysztof Zdziarski adf_processes_release(void *data)
348266b0663SKrzysztof Zdziarski {
349266b0663SKrzysztof Zdziarski struct adf_processes_priv_data *prv_data = NULL;
350266b0663SKrzysztof Zdziarski
351266b0663SKrzysztof Zdziarski prv_data = (struct adf_processes_priv_data *)data;
352266b0663SKrzysztof Zdziarski sx_xlock(&processes_list_sema);
353266b0663SKrzysztof Zdziarski list_del(&prv_data->list);
354266b0663SKrzysztof Zdziarski sx_xunlock(&processes_list_sema);
355266b0663SKrzysztof Zdziarski free(prv_data, M_QAT);
356266b0663SKrzysztof Zdziarski }
357266b0663SKrzysztof Zdziarski
358266b0663SKrzysztof Zdziarski int
adf_processes_dev_register(void)359266b0663SKrzysztof Zdziarski adf_processes_dev_register(void)
360266b0663SKrzysztof Zdziarski {
361266b0663SKrzysztof Zdziarski return adf_chr_drv_create();
362266b0663SKrzysztof Zdziarski }
363266b0663SKrzysztof Zdziarski
364266b0663SKrzysztof Zdziarski void
adf_processes_dev_unregister(void)365266b0663SKrzysztof Zdziarski adf_processes_dev_unregister(void)
366266b0663SKrzysztof Zdziarski {
367266b0663SKrzysztof Zdziarski adf_chr_drv_destroy();
368266b0663SKrzysztof Zdziarski }
369266b0663SKrzysztof Zdziarski
370266b0663SKrzysztof Zdziarski static void
adf_state_callout_notify_ev(void * arg)371266b0663SKrzysztof Zdziarski adf_state_callout_notify_ev(void *arg)
372266b0663SKrzysztof Zdziarski {
373266b0663SKrzysztof Zdziarski int notified = 0;
374266b0663SKrzysztof Zdziarski struct adf_state_priv_data *priv = NULL;
375266b0663SKrzysztof Zdziarski struct entry_proc_events *proc_events = NULL;
376266b0663SKrzysztof Zdziarski
377266b0663SKrzysztof Zdziarski SLIST_FOREACH (proc_events, &proc_events_head, entries_proc_events) {
378266b0663SKrzysztof Zdziarski if (!STAILQ_EMPTY(&proc_events->proc_events->state_head)) {
379266b0663SKrzysztof Zdziarski notified = 1;
380266b0663SKrzysztof Zdziarski priv = proc_events->proc_events;
381266b0663SKrzysztof Zdziarski wakeup(priv);
382266b0663SKrzysztof Zdziarski selwakeup(&priv->rsel);
383266b0663SKrzysztof Zdziarski KNOTE_UNLOCKED(&priv->rsel.si_note, 0);
384266b0663SKrzysztof Zdziarski }
385266b0663SKrzysztof Zdziarski }
386266b0663SKrzysztof Zdziarski if (notified)
387266b0663SKrzysztof Zdziarski callout_schedule(&callout, ADF_STATE_CALLOUT_TIME);
388266b0663SKrzysztof Zdziarski }
389266b0663SKrzysztof Zdziarski
390266b0663SKrzysztof Zdziarski static void
adf_state_set(int dev,enum adf_event event)391266b0663SKrzysztof Zdziarski adf_state_set(int dev, enum adf_event event)
392266b0663SKrzysztof Zdziarski {
393266b0663SKrzysztof Zdziarski struct adf_accel_dev *accel_dev = NULL;
394266b0663SKrzysztof Zdziarski struct state_head *head = NULL;
395266b0663SKrzysztof Zdziarski struct entry_proc_events *proc_events = NULL;
396266b0663SKrzysztof Zdziarski struct entry_state *state = NULL;
397266b0663SKrzysztof Zdziarski
398266b0663SKrzysztof Zdziarski accel_dev = adf_devmgr_get_dev_by_id(dev);
399266b0663SKrzysztof Zdziarski if (!accel_dev)
400266b0663SKrzysztof Zdziarski return;
401266b0663SKrzysztof Zdziarski mtx_lock(&mtx);
402266b0663SKrzysztof Zdziarski SLIST_FOREACH (proc_events, &proc_events_head, entries_proc_events) {
403266b0663SKrzysztof Zdziarski state = NULL;
404266b0663SKrzysztof Zdziarski head = &proc_events->proc_events->state_head;
405266b0663SKrzysztof Zdziarski state = malloc(sizeof(struct entry_state),
406266b0663SKrzysztof Zdziarski M_QAT,
407266b0663SKrzysztof Zdziarski M_NOWAIT | M_ZERO);
408266b0663SKrzysztof Zdziarski if (!state)
409266b0663SKrzysztof Zdziarski continue;
410266b0663SKrzysztof Zdziarski state->state.dev_state = event;
411266b0663SKrzysztof Zdziarski state->state.dev_id = dev;
412266b0663SKrzysztof Zdziarski STAILQ_INSERT_TAIL(head, state, entries_state);
413266b0663SKrzysztof Zdziarski if (event == ADF_EVENT_STOP) {
414266b0663SKrzysztof Zdziarski state = NULL;
415266b0663SKrzysztof Zdziarski state = malloc(sizeof(struct entry_state),
416266b0663SKrzysztof Zdziarski M_QAT,
417266b0663SKrzysztof Zdziarski M_NOWAIT | M_ZERO);
418266b0663SKrzysztof Zdziarski if (!state)
419266b0663SKrzysztof Zdziarski continue;
420266b0663SKrzysztof Zdziarski state->state.dev_state = ADF_EVENT_SHUTDOWN;
421266b0663SKrzysztof Zdziarski state->state.dev_id = dev;
422266b0663SKrzysztof Zdziarski STAILQ_INSERT_TAIL(head, state, entries_state);
423266b0663SKrzysztof Zdziarski }
424266b0663SKrzysztof Zdziarski }
425266b0663SKrzysztof Zdziarski mtx_unlock(&mtx);
426*22cf89c9SPiotr Kasierski callout_schedule(&callout, ADF_STATE_CALLOUT_TIME);
427266b0663SKrzysztof Zdziarski }
428266b0663SKrzysztof Zdziarski
429266b0663SKrzysztof Zdziarski static int
adf_state_event_handler(struct adf_accel_dev * accel_dev,enum adf_event event)430266b0663SKrzysztof Zdziarski adf_state_event_handler(struct adf_accel_dev *accel_dev, enum adf_event event)
431266b0663SKrzysztof Zdziarski {
432266b0663SKrzysztof Zdziarski int ret = 0;
433266b0663SKrzysztof Zdziarski
434266b0663SKrzysztof Zdziarski #if defined(QAT_UIO) && defined(QAT_DBG)
435266b0663SKrzysztof Zdziarski if (event > ADF_EVENT_DBG_SHUTDOWN)
436266b0663SKrzysztof Zdziarski return -EINVAL;
437266b0663SKrzysztof Zdziarski #else
438266b0663SKrzysztof Zdziarski if (event > ADF_EVENT_ERROR)
439266b0663SKrzysztof Zdziarski return -EINVAL;
440266b0663SKrzysztof Zdziarski #endif /* defined(QAT_UIO) && defined(QAT_DBG) */
441266b0663SKrzysztof Zdziarski
442266b0663SKrzysztof Zdziarski switch (event) {
443266b0663SKrzysztof Zdziarski case ADF_EVENT_INIT:
444266b0663SKrzysztof Zdziarski return ret;
445266b0663SKrzysztof Zdziarski case ADF_EVENT_SHUTDOWN:
446266b0663SKrzysztof Zdziarski return ret;
447266b0663SKrzysztof Zdziarski case ADF_EVENT_RESTARTING:
448266b0663SKrzysztof Zdziarski break;
449266b0663SKrzysztof Zdziarski case ADF_EVENT_RESTARTED:
450266b0663SKrzysztof Zdziarski break;
451266b0663SKrzysztof Zdziarski case ADF_EVENT_START:
452266b0663SKrzysztof Zdziarski return ret;
453266b0663SKrzysztof Zdziarski case ADF_EVENT_STOP:
454266b0663SKrzysztof Zdziarski break;
455266b0663SKrzysztof Zdziarski case ADF_EVENT_ERROR:
456266b0663SKrzysztof Zdziarski break;
457266b0663SKrzysztof Zdziarski #if defined(QAT_UIO) && defined(QAT_DBG)
458266b0663SKrzysztof Zdziarski case ADF_EVENT_PROC_CRASH:
459266b0663SKrzysztof Zdziarski break;
460266b0663SKrzysztof Zdziarski case ADF_EVENT_MANUAL_DUMP:
461266b0663SKrzysztof Zdziarski break;
462266b0663SKrzysztof Zdziarski case ADF_EVENT_SLICE_HANG:
463266b0663SKrzysztof Zdziarski break;
464266b0663SKrzysztof Zdziarski case ADF_EVENT_DBG_SHUTDOWN:
465266b0663SKrzysztof Zdziarski break;
466266b0663SKrzysztof Zdziarski #endif /* defined(QAT_UIO) && defined(QAT_DBG) */
467266b0663SKrzysztof Zdziarski default:
468266b0663SKrzysztof Zdziarski return -1;
469266b0663SKrzysztof Zdziarski }
470266b0663SKrzysztof Zdziarski
471266b0663SKrzysztof Zdziarski adf_state_set(accel_dev->accel_id, event);
472266b0663SKrzysztof Zdziarski
473266b0663SKrzysztof Zdziarski return 0;
474266b0663SKrzysztof Zdziarski }
475266b0663SKrzysztof Zdziarski
476266b0663SKrzysztof Zdziarski static int
adf_state_kqfilter(struct cdev * dev,struct knote * kn)477266b0663SKrzysztof Zdziarski adf_state_kqfilter(struct cdev *dev, struct knote *kn)
478266b0663SKrzysztof Zdziarski {
479266b0663SKrzysztof Zdziarski struct adf_state_priv_data *priv;
480266b0663SKrzysztof Zdziarski
481266b0663SKrzysztof Zdziarski mtx_lock(&mtx);
482266b0663SKrzysztof Zdziarski priv = dev->si_drv1;
483266b0663SKrzysztof Zdziarski switch (kn->kn_filter) {
484266b0663SKrzysztof Zdziarski case EVFILT_READ:
485266b0663SKrzysztof Zdziarski kn->kn_fop = &adf_state_read_filterops;
486266b0663SKrzysztof Zdziarski kn->kn_hook = priv;
487*22cf89c9SPiotr Kasierski knlist_add(&priv->rsel.si_note, kn, 1);
488266b0663SKrzysztof Zdziarski mtx_unlock(&mtx);
489266b0663SKrzysztof Zdziarski return 0;
490266b0663SKrzysztof Zdziarski default:
491266b0663SKrzysztof Zdziarski mtx_unlock(&mtx);
492266b0663SKrzysztof Zdziarski return -EINVAL;
493266b0663SKrzysztof Zdziarski }
494266b0663SKrzysztof Zdziarski }
495266b0663SKrzysztof Zdziarski
496266b0663SKrzysztof Zdziarski static int
adf_state_kqread_event(struct knote * kn,long hint)497266b0663SKrzysztof Zdziarski adf_state_kqread_event(struct knote *kn, long hint)
498266b0663SKrzysztof Zdziarski {
499266b0663SKrzysztof Zdziarski return 1;
500266b0663SKrzysztof Zdziarski }
501266b0663SKrzysztof Zdziarski
502266b0663SKrzysztof Zdziarski static void
adf_state_kqread_detach(struct knote * kn)503266b0663SKrzysztof Zdziarski adf_state_kqread_detach(struct knote *kn)
504266b0663SKrzysztof Zdziarski {
505266b0663SKrzysztof Zdziarski struct adf_state_priv_data *priv = NULL;
506266b0663SKrzysztof Zdziarski
507266b0663SKrzysztof Zdziarski mtx_lock(&mtx);
508266b0663SKrzysztof Zdziarski if (!kn) {
509266b0663SKrzysztof Zdziarski mtx_unlock(&mtx);
510266b0663SKrzysztof Zdziarski return;
511266b0663SKrzysztof Zdziarski }
512266b0663SKrzysztof Zdziarski priv = kn->kn_hook;
513266b0663SKrzysztof Zdziarski if (!priv) {
514266b0663SKrzysztof Zdziarski mtx_unlock(&mtx);
515266b0663SKrzysztof Zdziarski return;
516266b0663SKrzysztof Zdziarski }
517266b0663SKrzysztof Zdziarski knlist_remove(&priv->rsel.si_note, kn, 1);
518266b0663SKrzysztof Zdziarski mtx_unlock(&mtx);
519266b0663SKrzysztof Zdziarski }
520266b0663SKrzysztof Zdziarski
521266b0663SKrzysztof Zdziarski void
adf_state_init(void)522266b0663SKrzysztof Zdziarski adf_state_init(void)
523266b0663SKrzysztof Zdziarski {
524266b0663SKrzysztof Zdziarski adf_state_dev = make_dev(&adf_state_cdevsw,
525266b0663SKrzysztof Zdziarski 0,
526266b0663SKrzysztof Zdziarski UID_ROOT,
527266b0663SKrzysztof Zdziarski GID_WHEEL,
528266b0663SKrzysztof Zdziarski 0600,
529266b0663SKrzysztof Zdziarski "%s",
530266b0663SKrzysztof Zdziarski ADF_DEV_STATE_NAME);
531266b0663SKrzysztof Zdziarski SLIST_INIT(&proc_events_head);
532266b0663SKrzysztof Zdziarski mtx_init(&mtx, mtx_name, NULL, MTX_DEF);
533*22cf89c9SPiotr Kasierski mtx_init(&callout_mtx, mtx_callout_name, NULL, MTX_DEF);
534*22cf89c9SPiotr Kasierski callout_init_mtx(&callout, &callout_mtx, 0);
535266b0663SKrzysztof Zdziarski explicit_bzero(&adf_state_hndl, sizeof(adf_state_hndl));
536266b0663SKrzysztof Zdziarski adf_state_hndl.event_hld = adf_state_event_handler;
537266b0663SKrzysztof Zdziarski adf_state_hndl.name = "adf_state_event_handler";
538266b0663SKrzysztof Zdziarski adf_service_register(&adf_state_hndl);
539266b0663SKrzysztof Zdziarski callout_reset(&callout,
540266b0663SKrzysztof Zdziarski ADF_STATE_CALLOUT_TIME,
541266b0663SKrzysztof Zdziarski adf_state_callout_notify_ev,
542266b0663SKrzysztof Zdziarski NULL);
543266b0663SKrzysztof Zdziarski }
544266b0663SKrzysztof Zdziarski
545266b0663SKrzysztof Zdziarski void
adf_state_destroy(void)546266b0663SKrzysztof Zdziarski adf_state_destroy(void)
547266b0663SKrzysztof Zdziarski {
548266b0663SKrzysztof Zdziarski struct entry_proc_events *proc_events = NULL;
549266b0663SKrzysztof Zdziarski
550266b0663SKrzysztof Zdziarski adf_service_unregister(&adf_state_hndl);
551*22cf89c9SPiotr Kasierski mtx_lock(&callout_mtx);
552266b0663SKrzysztof Zdziarski callout_stop(&callout);
553*22cf89c9SPiotr Kasierski mtx_unlock(&callout_mtx);
554*22cf89c9SPiotr Kasierski mtx_destroy(&callout_mtx);
555*22cf89c9SPiotr Kasierski mtx_lock(&mtx);
556266b0663SKrzysztof Zdziarski while (!SLIST_EMPTY(&proc_events_head)) {
557266b0663SKrzysztof Zdziarski proc_events = SLIST_FIRST(&proc_events_head);
558266b0663SKrzysztof Zdziarski SLIST_REMOVE_HEAD(&proc_events_head, entries_proc_events);
559266b0663SKrzysztof Zdziarski free(proc_events, M_QAT);
560266b0663SKrzysztof Zdziarski }
561266b0663SKrzysztof Zdziarski mtx_unlock(&mtx);
562266b0663SKrzysztof Zdziarski mtx_destroy(&mtx);
563*22cf89c9SPiotr Kasierski destroy_dev(adf_state_dev);
564266b0663SKrzysztof Zdziarski }
565266b0663SKrzysztof Zdziarski
566266b0663SKrzysztof Zdziarski static int
adf_state_open(struct cdev * dev,int oflags,int devtype,struct thread * td)567266b0663SKrzysztof Zdziarski adf_state_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
568266b0663SKrzysztof Zdziarski {
569266b0663SKrzysztof Zdziarski struct adf_state_priv_data *prv_data = NULL;
570266b0663SKrzysztof Zdziarski struct entry_proc_events *entry_proc_events = NULL;
571266b0663SKrzysztof Zdziarski int ret = 0;
572266b0663SKrzysztof Zdziarski
573266b0663SKrzysztof Zdziarski prv_data = malloc(sizeof(*prv_data), M_QAT, M_WAITOK | M_ZERO);
574266b0663SKrzysztof Zdziarski entry_proc_events =
575266b0663SKrzysztof Zdziarski malloc(sizeof(struct entry_proc_events), M_QAT, M_WAITOK | M_ZERO);
576266b0663SKrzysztof Zdziarski mtx_lock(&mtx);
577266b0663SKrzysztof Zdziarski prv_data->cdev = dev;
578266b0663SKrzysztof Zdziarski prv_data->cdev->si_drv1 = prv_data;
579266b0663SKrzysztof Zdziarski knlist_init_mtx(&prv_data->rsel.si_note, &mtx);
580266b0663SKrzysztof Zdziarski STAILQ_INIT(&prv_data->state_head);
581266b0663SKrzysztof Zdziarski entry_proc_events->proc_events = prv_data;
582266b0663SKrzysztof Zdziarski SLIST_INSERT_HEAD(&proc_events_head,
583266b0663SKrzysztof Zdziarski entry_proc_events,
584266b0663SKrzysztof Zdziarski entries_proc_events);
585*22cf89c9SPiotr Kasierski mtx_unlock(&mtx);
586266b0663SKrzysztof Zdziarski ret = devfs_set_cdevpriv(prv_data, adf_state_release);
587266b0663SKrzysztof Zdziarski if (ret) {
588266b0663SKrzysztof Zdziarski SLIST_REMOVE(&proc_events_head,
589266b0663SKrzysztof Zdziarski entry_proc_events,
590266b0663SKrzysztof Zdziarski entry_proc_events,
591266b0663SKrzysztof Zdziarski entries_proc_events);
592266b0663SKrzysztof Zdziarski free(entry_proc_events, M_QAT);
593266b0663SKrzysztof Zdziarski free(prv_data, M_QAT);
594266b0663SKrzysztof Zdziarski }
595266b0663SKrzysztof Zdziarski callout_schedule(&callout, ADF_STATE_CALLOUT_TIME);
596266b0663SKrzysztof Zdziarski return ret;
597266b0663SKrzysztof Zdziarski }
598266b0663SKrzysztof Zdziarski
599266b0663SKrzysztof Zdziarski static int
adf_state_read(struct cdev * dev,struct uio * uio,int ioflag)600266b0663SKrzysztof Zdziarski adf_state_read(struct cdev *dev, struct uio *uio, int ioflag)
601266b0663SKrzysztof Zdziarski {
602266b0663SKrzysztof Zdziarski int ret = 0;
603266b0663SKrzysztof Zdziarski struct adf_state_priv_data *prv_data = NULL;
604266b0663SKrzysztof Zdziarski struct state_head *state_head = NULL;
605266b0663SKrzysztof Zdziarski struct entry_state *entry_state = NULL;
606266b0663SKrzysztof Zdziarski struct adf_state *state = NULL;
607266b0663SKrzysztof Zdziarski struct entry_proc_events *proc_events = NULL;
608266b0663SKrzysztof Zdziarski
609266b0663SKrzysztof Zdziarski mtx_lock(&mtx);
610266b0663SKrzysztof Zdziarski ret = devfs_get_cdevpriv((void **)&prv_data);
611266b0663SKrzysztof Zdziarski if (ret) {
612266b0663SKrzysztof Zdziarski mtx_unlock(&mtx);
613266b0663SKrzysztof Zdziarski return 0;
614266b0663SKrzysztof Zdziarski }
615266b0663SKrzysztof Zdziarski state_head = &prv_data->state_head;
616266b0663SKrzysztof Zdziarski if (STAILQ_EMPTY(state_head)) {
617266b0663SKrzysztof Zdziarski mtx_unlock(&mtx);
618266b0663SKrzysztof Zdziarski return 0;
619266b0663SKrzysztof Zdziarski }
620266b0663SKrzysztof Zdziarski entry_state = STAILQ_FIRST(state_head);
621266b0663SKrzysztof Zdziarski state = &entry_state->state;
622266b0663SKrzysztof Zdziarski ret = uiomove(state, sizeof(struct adf_state), uio);
623266b0663SKrzysztof Zdziarski if (!ret && !STAILQ_EMPTY(state_head)) {
624266b0663SKrzysztof Zdziarski STAILQ_REMOVE_HEAD(state_head, entries_state);
625266b0663SKrzysztof Zdziarski free(entry_state, M_QAT);
626266b0663SKrzysztof Zdziarski }
627266b0663SKrzysztof Zdziarski SLIST_FOREACH (proc_events, &proc_events_head, entries_proc_events) {
628266b0663SKrzysztof Zdziarski if (!STAILQ_EMPTY(&proc_events->proc_events->state_head)) {
629266b0663SKrzysztof Zdziarski prv_data = proc_events->proc_events;
630266b0663SKrzysztof Zdziarski wakeup(prv_data);
631266b0663SKrzysztof Zdziarski selwakeup(&prv_data->rsel);
632266b0663SKrzysztof Zdziarski KNOTE_UNLOCKED(&prv_data->rsel.si_note, 0);
633266b0663SKrzysztof Zdziarski }
634266b0663SKrzysztof Zdziarski }
635266b0663SKrzysztof Zdziarski mtx_unlock(&mtx);
636*22cf89c9SPiotr Kasierski callout_schedule(&callout, ADF_STATE_CALLOUT_TIME);
637266b0663SKrzysztof Zdziarski return ret;
638266b0663SKrzysztof Zdziarski }
639266b0663SKrzysztof Zdziarski
640266b0663SKrzysztof Zdziarski static void
adf_state_release(void * data)641266b0663SKrzysztof Zdziarski adf_state_release(void *data)
642266b0663SKrzysztof Zdziarski {
643266b0663SKrzysztof Zdziarski struct adf_state_priv_data *prv_data = NULL;
644266b0663SKrzysztof Zdziarski struct entry_state *entry_state = NULL;
645266b0663SKrzysztof Zdziarski struct entry_proc_events *entry_proc_events = NULL;
646266b0663SKrzysztof Zdziarski struct entry_proc_events *tmp = NULL;
647266b0663SKrzysztof Zdziarski
648266b0663SKrzysztof Zdziarski mtx_lock(&mtx);
649266b0663SKrzysztof Zdziarski prv_data = (struct adf_state_priv_data *)data;
650266b0663SKrzysztof Zdziarski knlist_delete(&prv_data->rsel.si_note, curthread, 1);
651266b0663SKrzysztof Zdziarski knlist_destroy(&prv_data->rsel.si_note);
652266b0663SKrzysztof Zdziarski seldrain(&prv_data->rsel);
653266b0663SKrzysztof Zdziarski while (!STAILQ_EMPTY(&prv_data->state_head)) {
654266b0663SKrzysztof Zdziarski entry_state = STAILQ_FIRST(&prv_data->state_head);
655266b0663SKrzysztof Zdziarski STAILQ_REMOVE_HEAD(&prv_data->state_head, entries_state);
656266b0663SKrzysztof Zdziarski free(entry_state, M_QAT);
657266b0663SKrzysztof Zdziarski }
658266b0663SKrzysztof Zdziarski SLIST_FOREACH_SAFE (entry_proc_events,
659266b0663SKrzysztof Zdziarski &proc_events_head,
660266b0663SKrzysztof Zdziarski entries_proc_events,
661266b0663SKrzysztof Zdziarski tmp) {
662266b0663SKrzysztof Zdziarski if (entry_proc_events->proc_events == prv_data) {
663266b0663SKrzysztof Zdziarski SLIST_REMOVE(&proc_events_head,
664266b0663SKrzysztof Zdziarski entry_proc_events,
665266b0663SKrzysztof Zdziarski entry_proc_events,
666266b0663SKrzysztof Zdziarski entries_proc_events);
667266b0663SKrzysztof Zdziarski free(entry_proc_events, M_QAT);
668266b0663SKrzysztof Zdziarski }
669266b0663SKrzysztof Zdziarski }
670266b0663SKrzysztof Zdziarski free(prv_data, M_QAT);
671266b0663SKrzysztof Zdziarski mtx_unlock(&mtx);
672266b0663SKrzysztof Zdziarski }
673