xref: /freebsd/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c (revision 866dc4bd81398b478daefe4b7447b92422b4a06c)
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