xref: /freebsd/sys/dev/qat/qat_api/common/ctrl/sal_compression.c (revision 43e29d03f416d7dda52112a29600a7c82ee1a91e)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 /**
5  *****************************************************************************
6  * @file sal_compression.c
7  *
8  * @ingroup SalCtrl
9  *
10  * @description
11  *    This file contains the sal implementation for compression.
12  *
13  *****************************************************************************/
14 
15 /* QAT-API includes */
16 #include "cpa.h"
17 #include "cpa_dc.h"
18 
19 /* QAT utils includes */
20 #include "qat_utils.h"
21 
22 /* ADF includes */
23 #include "icp_adf_init.h"
24 #include "icp_adf_transport.h"
25 #include "icp_accel_devices.h"
26 #include "icp_adf_cfg.h"
27 #include "icp_adf_accel_mgr.h"
28 #include "icp_adf_poll.h"
29 #include "icp_adf_debug.h"
30 #include "icp_adf_esram.h"
31 #include "icp_qat_hw.h"
32 
33 /* SAL includes */
34 #include "lac_mem.h"
35 #include "lac_common.h"
36 #include "lac_mem_pools.h"
37 #include "sal_statistics.h"
38 #include "lac_list.h"
39 #include "icp_sal_poll.h"
40 #include "sal_types_compression.h"
41 #include "dc_session.h"
42 #include "dc_datapath.h"
43 #include "dc_stats.h"
44 #include "lac_sal.h"
45 #include "lac_sal_ctrl.h"
46 #include "sal_string_parse.h"
47 #include "sal_service_state.h"
48 #include "lac_buffer_desc.h"
49 #include "icp_qat_fw_comp.h"
50 #include "icp_qat_hw_20_comp_defs.h"
51 #include "icp_sal_versions.h"
52 
53 /* C string null terminator size */
54 #define SAL_NULL_TERM_SIZE 1
55 
56 /* Type to access extended features bit fields */
57 typedef struct dc_extended_features_s {
58 	unsigned is_cnv : 1; /* Bit<0> */
59 	unsigned padding : 7;
60 	unsigned is_cnvnr : 1; /* Bit<8> */
61 	unsigned not_used : 23;
62 } dc_extd_ftrs_t;
63 
64 /*
65  * Prints statistics for a compression instance
66  */
67 static int
68 SalCtrl_CompresionDebug(void *private_data, char *data, int size, int offset)
69 {
70 	sal_compression_service_t *pCompressionService =
71 	    (sal_compression_service_t *)private_data;
72 	CpaStatus status = CPA_STATUS_SUCCESS;
73 	CpaDcStats dcStats = { 0 };
74 	Cpa32S len = 0;
75 
76 	status = cpaDcGetStats(pCompressionService, &dcStats);
77 	if (status != CPA_STATUS_SUCCESS) {
78 		QAT_UTILS_LOG("cpaDcGetStats returned error.\n");
79 		return (-1);
80 	}
81 
82 	/* Engine Info */
83 	if (NULL != pCompressionService->debug_file) {
84 		len += snprintf(data + len,
85 				size - len,
86 				SEPARATOR BORDER
87 				" Statistics for Instance %24s | \n" SEPARATOR,
88 				pCompressionService->debug_file->name);
89 	}
90 
91 	/* Perform Info */
92 	len += snprintf(data + len,
93 			size - len,
94 			BORDER " DC comp Requests:               %16llu " BORDER
95 			       "\n" BORDER
96 			       " DC comp Request Errors:         %16llu " BORDER
97 			       "\n" BORDER
98 			       " DC comp Completed:              %16llu " BORDER
99 			       "\n" BORDER
100 			       " DC comp Completed Errors:       %16llu " BORDER
101 			       "\n" SEPARATOR,
102 			(long long unsigned int)dcStats.numCompRequests,
103 			(long long unsigned int)dcStats.numCompRequestsErrors,
104 			(long long unsigned int)dcStats.numCompCompleted,
105 			(long long unsigned int)dcStats.numCompCompletedErrors);
106 
107 	/* Perform Info */
108 	len += snprintf(
109 	    data + len,
110 	    size - len,
111 	    BORDER " DC decomp Requests:             %16llu " BORDER "\n" BORDER
112 		   " DC decomp Request Errors:       %16llu " BORDER "\n" BORDER
113 		   " DC decomp Completed:            %16llu " BORDER "\n" BORDER
114 		   " DC decomp Completed Errors:     %16llu " BORDER
115 		   "\n" SEPARATOR,
116 	    (long long unsigned int)dcStats.numDecompRequests,
117 	    (long long unsigned int)dcStats.numDecompRequestsErrors,
118 	    (long long unsigned int)dcStats.numDecompCompleted,
119 	    (long long unsigned int)dcStats.numDecompCompletedErrors);
120 	return 0;
121 }
122 
123 /* Initialise device specific information needed by compression service */
124 static CpaStatus
125 SalCtrl_CompressionInit_CompData(icp_accel_dev_t *device,
126 				 sal_compression_service_t *pCompService)
127 {
128 	int level = 0;
129 	pCompService->comp_device_data.asbEnableSupport = CPA_FALSE;
130 	pCompService->comp_device_data.uniqueCompressionLevels[0] = CPA_FALSE;
131 
132 	switch (device->deviceType) {
133 	case DEVICE_DH895XCC:
134 	case DEVICE_DH895XCCVF:
135 		pCompService->generic_service_info.integrityCrcCheck =
136 		    CPA_FALSE;
137 		pCompService->numInterBuffs =
138 		    DC_QAT_MAX_NUM_INTER_BUFFERS_6COMP_SLICES;
139 		pCompService->comp_device_data.minOutputBuffSize =
140 		    DC_DEST_BUFFER_STA_MIN_SIZE;
141 		pCompService->comp_device_data.oddByteDecompNobFinal = CPA_TRUE;
142 		pCompService->comp_device_data.oddByteDecompInterim = CPA_FALSE;
143 		pCompService->comp_device_data.translatorOverflow = CPA_FALSE;
144 		pCompService->comp_device_data.useDevRam =
145 		    ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
146 		pCompService->comp_device_data.enableDmm =
147 		    ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_DISABLED;
148 
149 		pCompService->comp_device_data.inflateContextSize =
150 		    DC_INFLATE_CONTEXT_SIZE;
151 		pCompService->comp_device_data.highestHwCompressionDepth =
152 		    ICP_QAT_HW_COMPRESSION_DEPTH_16;
153 
154 		pCompService->comp_device_data.windowSizeMask =
155 		    (1 << DC_8K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
156 		pCompService->comp_device_data.cnvnrSupported = CPA_FALSE;
157 		for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) {
158 			switch (level) {
159 			case CPA_DC_L1:
160 			case CPA_DC_L2:
161 			case CPA_DC_L3:
162 			case CPA_DC_L4:
163 				pCompService->comp_device_data
164 				    .uniqueCompressionLevels[level] = CPA_TRUE;
165 				break;
166 			default:
167 				pCompService->comp_device_data
168 				    .uniqueCompressionLevels[level] = CPA_FALSE;
169 				break;
170 			}
171 		}
172 		pCompService->comp_device_data.numCompressionLevels =
173 		    DC_NUM_COMPRESSION_LEVELS;
174 		break;
175 	case DEVICE_C3XXX:
176 	case DEVICE_C3XXXVF:
177 	case DEVICE_200XX:
178 	case DEVICE_200XXVF:
179 		pCompService->generic_service_info.integrityCrcCheck =
180 		    CPA_FALSE;
181 		pCompService->numInterBuffs =
182 		    DC_QAT_MAX_NUM_INTER_BUFFERS_6COMP_SLICES;
183 		pCompService->comp_device_data.oddByteDecompNobFinal =
184 		    CPA_FALSE;
185 		pCompService->comp_device_data.oddByteDecompInterim = CPA_TRUE;
186 		pCompService->comp_device_data.translatorOverflow = CPA_FALSE;
187 		pCompService->comp_device_data.useDevRam =
188 		    ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_USED_AS_INTMD_BUF;
189 		pCompService->comp_device_data.inflateContextSize =
190 		    DC_INFLATE_EH_CONTEXT_SIZE;
191 		pCompService->comp_device_data.highestHwCompressionDepth =
192 		    ICP_QAT_HW_COMPRESSION_DEPTH_16;
193 		pCompService->comp_device_data.windowSizeMask =
194 		    (1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
195 		pCompService->comp_device_data.minOutputBuffSize =
196 		    DC_DEST_BUFFER_STA_MIN_SIZE;
197 		pCompService->comp_device_data.enableDmm =
198 		    ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
199 
200 		pCompService->comp_device_data.cnvnrSupported = CPA_TRUE;
201 
202 		for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) {
203 			switch (level) {
204 			case CPA_DC_L1:
205 			case CPA_DC_L2:
206 			case CPA_DC_L3:
207 			case CPA_DC_L4:
208 				pCompService->comp_device_data
209 				    .uniqueCompressionLevels[level] = CPA_TRUE;
210 				break;
211 			default:
212 				pCompService->comp_device_data
213 				    .uniqueCompressionLevels[level] = CPA_FALSE;
214 				break;
215 			}
216 		}
217 		pCompService->comp_device_data.numCompressionLevels =
218 		    DC_NUM_COMPRESSION_LEVELS;
219 		break;
220 	case DEVICE_C62X:
221 	case DEVICE_C62XVF:
222 		pCompService->generic_service_info.integrityCrcCheck =
223 		    CPA_FALSE;
224 		pCompService->numInterBuffs =
225 		    DC_QAT_MAX_NUM_INTER_BUFFERS_10COMP_SLICES;
226 		pCompService->comp_device_data.oddByteDecompNobFinal =
227 		    CPA_FALSE;
228 		pCompService->comp_device_data.oddByteDecompInterim = CPA_TRUE;
229 		pCompService->comp_device_data.translatorOverflow = CPA_FALSE;
230 		pCompService->comp_device_data.useDevRam =
231 		    ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
232 		pCompService->comp_device_data.inflateContextSize =
233 		    DC_INFLATE_EH_CONTEXT_SIZE;
234 		pCompService->comp_device_data.highestHwCompressionDepth =
235 		    ICP_QAT_HW_COMPRESSION_DEPTH_16;
236 		pCompService->comp_device_data.windowSizeMask =
237 		    (1 << DC_4K_WINDOW_SIZE | 1 << DC_8K_WINDOW_SIZE |
238 		     1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
239 		pCompService->comp_device_data.minOutputBuffSize =
240 		    DC_DEST_BUFFER_STA_MIN_SIZE;
241 		pCompService->comp_device_data.minOutputBuffSizeDynamic =
242 		    pCompService->comp_device_data.minOutputBuffSize;
243 		pCompService->comp_device_data.enableDmm =
244 		    ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
245 		pCompService->comp_device_data.cnvnrSupported = CPA_TRUE;
246 
247 		for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) {
248 			switch (level) {
249 			case CPA_DC_L1:
250 			case CPA_DC_L2:
251 			case CPA_DC_L3:
252 			case CPA_DC_L4:
253 				pCompService->comp_device_data
254 				    .uniqueCompressionLevels[level] = CPA_TRUE;
255 				break;
256 			default:
257 				pCompService->comp_device_data
258 				    .uniqueCompressionLevels[level] = CPA_FALSE;
259 				break;
260 			}
261 		}
262 		pCompService->comp_device_data.numCompressionLevels =
263 		    DC_NUM_COMPRESSION_LEVELS;
264 		break;
265 	case DEVICE_C4XXX:
266 	case DEVICE_C4XXXVF:
267 		pCompService->generic_service_info.integrityCrcCheck = CPA_TRUE;
268 		pCompService->numInterBuffs =
269 		    DC_QAT_MAX_NUM_INTER_BUFFERS_24COMP_SLICES;
270 		pCompService->comp_device_data.minOutputBuffSize =
271 		    DC_DEST_BUFFER_MIN_SIZE;
272 		pCompService->comp_device_data.oddByteDecompNobFinal = CPA_TRUE;
273 		pCompService->comp_device_data.oddByteDecompInterim = CPA_TRUE;
274 		pCompService->comp_device_data.translatorOverflow = CPA_TRUE;
275 		if (pCompService->generic_service_info.capabilitiesMask &
276 		    ICP_ACCEL_CAPABILITIES_INLINE) {
277 			pCompService->comp_device_data.useDevRam =
278 			    ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_USED_AS_INTMD_BUF;
279 		} else {
280 			pCompService->comp_device_data.useDevRam =
281 			    ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
282 		}
283 		pCompService->comp_device_data.enableDmm =
284 		    ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
285 		pCompService->comp_device_data.inflateContextSize =
286 		    DC_INFLATE_EH_CONTEXT_SIZE;
287 		pCompService->comp_device_data.highestHwCompressionDepth =
288 		    ICP_QAT_HW_COMPRESSION_DEPTH_128;
289 		pCompService->comp_device_data.windowSizeMask =
290 		    (1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
291 		pCompService->comp_device_data.cnvnrSupported = CPA_TRUE;
292 
293 		for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) {
294 			switch (level) {
295 			case CPA_DC_L1:
296 			case CPA_DC_L2:
297 			case CPA_DC_L3:
298 			case CPA_DC_L4:
299 			case CPA_DC_L5:
300 				pCompService->comp_device_data
301 				    .uniqueCompressionLevels[level] = CPA_TRUE;
302 				break;
303 			default:
304 				pCompService->comp_device_data
305 				    .uniqueCompressionLevels[level] = CPA_FALSE;
306 				break;
307 			}
308 		}
309 		pCompService->comp_device_data.numCompressionLevels =
310 		    DC_NUM_COMPRESSION_LEVELS;
311 		break;
312 	case DEVICE_4XXX:
313 	case DEVICE_4XXXVF:
314 		pCompService->generic_service_info.integrityCrcCheck = CPA_TRUE;
315 		pCompService->numInterBuffs = 0;
316 		pCompService->comp_device_data.minOutputBuffSize =
317 		    DC_DEST_BUFFER_STA_MIN_SIZE_GEN4;
318 		pCompService->comp_device_data.minOutputBuffSizeDynamic =
319 		    DC_DEST_BUFFER_DYN_MIN_SIZE_GEN4;
320 		pCompService->comp_device_data.oddByteDecompNobFinal = CPA_TRUE;
321 		pCompService->comp_device_data.oddByteDecompInterim = CPA_FALSE;
322 		pCompService->comp_device_data.translatorOverflow = CPA_TRUE;
323 		pCompService->comp_device_data.useDevRam =
324 		    ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
325 		pCompService->comp_device_data.enableDmm =
326 		    ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
327 
328 		pCompService->comp_device_data.inflateContextSize =
329 		    DC_INFLATE_CONTEXT_SIZE;
330 		pCompService->comp_device_data.highestHwCompressionDepth =
331 		    ICP_QAT_HW_COMP_20_SEARCH_DEPTH_LEVEL_9;
332 		pCompService->comp_device_data.windowSizeMask =
333 		    (1 << DC_4K_WINDOW_SIZE | 1 << DC_8K_WINDOW_SIZE |
334 		     1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
335 		for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) {
336 			switch (level) {
337 			case CPA_DC_L1:
338 			case CPA_DC_L6:
339 			case CPA_DC_L9:
340 				pCompService->comp_device_data
341 				    .uniqueCompressionLevels[level] = CPA_TRUE;
342 				break;
343 			default:
344 				pCompService->comp_device_data
345 				    .uniqueCompressionLevels[level] = CPA_FALSE;
346 				break;
347 			}
348 		}
349 		pCompService->comp_device_data.numCompressionLevels =
350 		    DC_NUM_COMPRESSION_LEVELS;
351 		break;
352 	default:
353 		QAT_UTILS_LOG("Unknown device type! - %d.\n",
354 			      device->deviceType);
355 		return CPA_STATUS_FAIL;
356 	}
357 	return CPA_STATUS_SUCCESS;
358 }
359 
360 CpaStatus
361 SalCtrl_CompressionInit(icp_accel_dev_t *device, sal_service_t *service)
362 {
363 	CpaStatus status = CPA_STATUS_SUCCESS;
364 	Cpa32U numCompConcurrentReq = 0;
365 	Cpa32U request_ring_id = 0;
366 	Cpa32U response_ring_id = 0;
367 
368 	char adfGetParam[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
369 	char compMemPool[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
370 	char temp_string[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
371 	char temp_string2[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
372 	char *instance_name = NULL;
373 	sal_statistics_collection_t *pStatsCollection =
374 	    (sal_statistics_collection_t *)device->pQatStats;
375 	icp_resp_deliv_method rx_resp_type = ICP_RESP_TYPE_IRQ;
376 	sal_compression_service_t *pCompressionService =
377 	    (sal_compression_service_t *)service;
378 	Cpa32U msgSize = 0;
379 	char *section = DYN_SEC;
380 
381 	SAL_SERVICE_GOOD_FOR_INIT(pCompressionService);
382 
383 	pCompressionService->generic_service_info.state =
384 	    SAL_SERVICE_STATE_INITIALIZING;
385 
386 	if (CPA_FALSE == pCompressionService->generic_service_info.is_dyn) {
387 		section = icpGetProcessName();
388 	}
389 
390 	if (pStatsCollection == NULL) {
391 		return CPA_STATUS_FAIL;
392 	}
393 
394 	/* Get Config Info: Accel Num, bank Num, packageID,
395 				    coreAffinity, nodeAffinity and response mode
396 	   */
397 
398 	pCompressionService->acceleratorNum = 0;
399 
400 	/* Initialise device specific compression data */
401 	SalCtrl_CompressionInit_CompData(device, pCompressionService);
402 
403 	status = Sal_StringParsing(
404 	    "Dc",
405 	    pCompressionService->generic_service_info.instance,
406 	    "BankNumber",
407 	    temp_string);
408 	LAC_CHECK_STATUS(status);
409 	status =
410 	    icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
411 	if (CPA_STATUS_SUCCESS != status) {
412 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
413 			      temp_string);
414 		return status;
415 	}
416 
417 	pCompressionService->bankNum =
418 	    Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
419 
420 	status = Sal_StringParsing(
421 	    "Dc",
422 	    pCompressionService->generic_service_info.instance,
423 	    "IsPolled",
424 	    temp_string);
425 	LAC_CHECK_STATUS(status);
426 	status =
427 	    icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
428 	if (CPA_STATUS_SUCCESS != status) {
429 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
430 			      temp_string);
431 		return status;
432 	}
433 	pCompressionService->isPolled =
434 	    (Cpa8U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
435 
436 	/* User instances only support poll and epoll mode */
437 	if (SAL_RESP_POLL_CFG_FILE != pCompressionService->isPolled) {
438 		QAT_UTILS_LOG(
439 		    "IsPolled %u is not supported for user instance %s.\n",
440 		    pCompressionService->isPolled,
441 		    temp_string);
442 		return CPA_STATUS_FAIL;
443 	}
444 
445 	if (SAL_RESP_POLL_CFG_FILE == pCompressionService->isPolled) {
446 		rx_resp_type = ICP_RESP_TYPE_POLL;
447 	}
448 
449 	status = icp_adf_cfgGetParamValue(device,
450 					  LAC_CFG_SECTION_GENERAL,
451 					  ADF_DEV_PKG_ID,
452 					  adfGetParam);
453 	if (CPA_STATUS_SUCCESS != status) {
454 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
455 			      ADF_DEV_PKG_ID);
456 		return status;
457 	}
458 	pCompressionService->pkgID =
459 	    (Cpa16U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
460 
461 	status = icp_adf_cfgGetParamValue(device,
462 					  LAC_CFG_SECTION_GENERAL,
463 					  ADF_DEV_NODE_ID,
464 					  adfGetParam);
465 	if (CPA_STATUS_SUCCESS != status) {
466 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
467 			      ADF_DEV_NODE_ID);
468 		return status;
469 	}
470 	pCompressionService->nodeAffinity =
471 	    (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
472 
473 	/* In case of interrupt instance, use the bank affinity set by adf_ctl
474 	 * Otherwise, use the instance affinity for backwards compatibility */
475 	if (SAL_RESP_POLL_CFG_FILE != pCompressionService->isPolled) {
476 		/* Next need to read the [AcceleratorX] section of the config
477 		 * file */
478 		status = Sal_StringParsing("Accelerator",
479 					   pCompressionService->acceleratorNum,
480 					   "",
481 					   temp_string2);
482 		LAC_CHECK_STATUS(status);
483 
484 		status = Sal_StringParsing("Bank",
485 					   pCompressionService->bankNum,
486 					   "CoreAffinity",
487 					   temp_string);
488 		LAC_CHECK_STATUS(status);
489 	} else {
490 		strncpy(temp_string2,
491 			section,
492 			sizeof(temp_string2) - SAL_NULL_TERM_SIZE);
493 		temp_string2[SAL_CFG_MAX_VAL_LEN_IN_BYTES -
494 			     SAL_NULL_TERM_SIZE] = '\0';
495 
496 		status = Sal_StringParsing(
497 		    "Dc",
498 		    pCompressionService->generic_service_info.instance,
499 		    "CoreAffinity",
500 		    temp_string);
501 		LAC_CHECK_STATUS(status);
502 	}
503 
504 	status = icp_adf_cfgGetParamValue(device,
505 					  temp_string2,
506 					  temp_string,
507 					  adfGetParam);
508 	if (CPA_STATUS_SUCCESS != status) {
509 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
510 			      temp_string);
511 		return status;
512 	}
513 	pCompressionService->coreAffinity =
514 	    (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
515 
516 	status = Sal_StringParsing(
517 	    "Dc",
518 	    pCompressionService->generic_service_info.instance,
519 	    "NumConcurrentRequests",
520 	    temp_string);
521 	LAC_CHECK_STATUS(status);
522 	status =
523 	    icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
524 	if (CPA_STATUS_SUCCESS != status) {
525 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
526 			      temp_string);
527 		return status;
528 	}
529 
530 	numCompConcurrentReq =
531 	    (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
532 	if (validateConcurrRequest(numCompConcurrentReq)) {
533 		QAT_UTILS_LOG(
534 		    "Invalid NumConcurrentRequests, valid values are: {64, 128, 256, ... 32768, 65536}.\n");
535 		return CPA_STATUS_FAIL;
536 	}
537 
538 	/* ADF does not allow us to completely fill the ring for batch requests
539 	 */
540 	pCompressionService->maxNumCompConcurrentReq =
541 	    (numCompConcurrentReq - SAL_BATCH_SUBMIT_FREE_SPACE);
542 
543 	/* 1. Create transport handles */
544 	status = Sal_StringParsing(
545 	    "Dc",
546 	    pCompressionService->generic_service_info.instance,
547 	    "RingTx",
548 	    temp_string);
549 	LAC_CHECK_STATUS(status);
550 
551 	msgSize = LAC_QAT_DC_REQ_SZ_LW * LAC_LONG_WORD_IN_BYTES;
552 	status = icp_adf_transCreateHandle(
553 	    device,
554 	    ICP_TRANS_TYPE_ETR,
555 	    section,
556 	    pCompressionService->acceleratorNum,
557 	    pCompressionService->bankNum,
558 	    temp_string,
559 	    lac_getRingType(SAL_RING_TYPE_DC),
560 	    NULL,
561 	    ICP_RESP_TYPE_NONE,
562 	    numCompConcurrentReq,
563 	    msgSize,
564 	    (icp_comms_trans_handle *)&(
565 		pCompressionService->trans_handle_compression_tx));
566 	LAC_CHECK_STATUS(status);
567 
568 	if (icp_adf_transGetRingNum(
569 		pCompressionService->trans_handle_compression_tx,
570 		&request_ring_id) != CPA_STATUS_SUCCESS) {
571 		icp_adf_transReleaseHandle(
572 		    pCompressionService->trans_handle_compression_tx);
573 
574 		QAT_UTILS_LOG("Failed to get DC TX ring number.\n");
575 		return CPA_STATUS_FAIL;
576 	}
577 
578 	status = Sal_StringParsing(
579 	    "Dc",
580 	    pCompressionService->generic_service_info.instance,
581 	    "RingRx",
582 	    temp_string);
583 	if (CPA_STATUS_SUCCESS != status) {
584 		icp_adf_transReleaseHandle(
585 		    pCompressionService->trans_handle_compression_tx);
586 		return status;
587 	}
588 
589 	msgSize = LAC_QAT_DC_RESP_SZ_LW * LAC_LONG_WORD_IN_BYTES;
590 	status = icp_adf_transCreateHandle(
591 	    device,
592 	    ICP_TRANS_TYPE_ETR,
593 	    section,
594 	    pCompressionService->acceleratorNum,
595 	    pCompressionService->bankNum,
596 	    temp_string,
597 	    lac_getRingType(SAL_RING_TYPE_NONE),
598 	    (icp_trans_callback)dcCompression_ProcessCallback,
599 	    rx_resp_type,
600 	    numCompConcurrentReq,
601 	    msgSize,
602 	    (icp_comms_trans_handle *)&(
603 		pCompressionService->trans_handle_compression_rx));
604 	if (CPA_STATUS_SUCCESS != status) {
605 		icp_adf_transReleaseHandle(
606 		    pCompressionService->trans_handle_compression_tx);
607 		return status;
608 	}
609 
610 	if (icp_adf_transGetRingNum(
611 		pCompressionService->trans_handle_compression_rx,
612 		&response_ring_id) != CPA_STATUS_SUCCESS) {
613 		icp_adf_transReleaseHandle(
614 		    pCompressionService->trans_handle_compression_tx);
615 
616 		icp_adf_transReleaseHandle(
617 		    pCompressionService->trans_handle_compression_rx);
618 
619 		QAT_UTILS_LOG("Failed to get DC RX ring number.\n");
620 		return CPA_STATUS_FAIL;
621 	}
622 
623 	/* 2. Allocates memory pools */
624 
625 	/* Valid initialisation value for a pool ID */
626 	pCompressionService->compression_mem_pool = LAC_MEM_POOL_INIT_POOL_ID;
627 
628 	status = Sal_StringParsing(
629 	    "Comp",
630 	    pCompressionService->generic_service_info.instance,
631 	    "_MemPool",
632 	    compMemPool);
633 	if (CPA_STATUS_SUCCESS != status) {
634 		icp_adf_transReleaseHandle(
635 		    pCompressionService->trans_handle_compression_tx);
636 
637 		icp_adf_transReleaseHandle(
638 		    pCompressionService->trans_handle_compression_rx);
639 
640 		return status;
641 	}
642 
643 	status = Lac_MemPoolCreate(&pCompressionService->compression_mem_pool,
644 				   compMemPool,
645 				   (numCompConcurrentReq + 1),
646 				   sizeof(dc_compression_cookie_t),
647 				   LAC_64BYTE_ALIGNMENT,
648 				   CPA_FALSE,
649 				   pCompressionService->nodeAffinity);
650 	if (CPA_STATUS_SUCCESS != status) {
651 		icp_adf_transReleaseHandle(
652 		    pCompressionService->trans_handle_compression_tx);
653 
654 		icp_adf_transReleaseHandle(
655 		    pCompressionService->trans_handle_compression_rx);
656 
657 		return status;
658 	}
659 
660 	/* Init compression statistics */
661 	status = dcStatsInit(pCompressionService);
662 	if (CPA_STATUS_SUCCESS != status) {
663 		Lac_MemPoolDestroy(pCompressionService->compression_mem_pool);
664 
665 		icp_adf_transReleaseHandle(
666 		    pCompressionService->trans_handle_compression_tx);
667 
668 		icp_adf_transReleaseHandle(
669 		    pCompressionService->trans_handle_compression_rx);
670 
671 		return status;
672 	}
673 	if (CPA_TRUE == pStatsCollection->bDcStatsEnabled) {
674 		/* Get instance name for stats */
675 		instance_name = LAC_OS_MALLOC(ADF_CFG_MAX_VAL_LEN_IN_BYTES);
676 		if (NULL == instance_name) {
677 			Lac_MemPoolDestroy(
678 			    pCompressionService->compression_mem_pool);
679 
680 			icp_adf_transReleaseHandle(
681 			    pCompressionService->trans_handle_compression_tx);
682 
683 			icp_adf_transReleaseHandle(
684 			    pCompressionService->trans_handle_compression_rx);
685 
686 			return CPA_STATUS_RESOURCE;
687 		}
688 
689 		status = Sal_StringParsing(
690 		    "Dc",
691 		    pCompressionService->generic_service_info.instance,
692 		    "Name",
693 		    temp_string);
694 		if (CPA_STATUS_SUCCESS != status) {
695 			Lac_MemPoolDestroy(
696 			    pCompressionService->compression_mem_pool);
697 
698 			icp_adf_transReleaseHandle(
699 			    pCompressionService->trans_handle_compression_tx);
700 
701 			icp_adf_transReleaseHandle(
702 			    pCompressionService->trans_handle_compression_rx);
703 			LAC_OS_FREE(instance_name);
704 			return status;
705 		}
706 		status = icp_adf_cfgGetParamValue(device,
707 						  section,
708 						  temp_string,
709 						  adfGetParam);
710 		if (CPA_STATUS_SUCCESS != status) {
711 			QAT_UTILS_LOG("Failed to get %s from configuration.\n",
712 				      temp_string);
713 
714 			Lac_MemPoolDestroy(
715 			    pCompressionService->compression_mem_pool);
716 
717 			icp_adf_transReleaseHandle(
718 			    pCompressionService->trans_handle_compression_tx);
719 
720 			icp_adf_transReleaseHandle(
721 			    pCompressionService->trans_handle_compression_rx);
722 			LAC_OS_FREE(instance_name);
723 			return status;
724 		}
725 
726 		snprintf(instance_name,
727 			 ADF_CFG_MAX_VAL_LEN_IN_BYTES,
728 			 "%s",
729 			 adfGetParam);
730 
731 		pCompressionService->debug_file =
732 		    LAC_OS_MALLOC(sizeof(debug_file_info_t));
733 		if (NULL == pCompressionService->debug_file) {
734 			Lac_MemPoolDestroy(
735 			    pCompressionService->compression_mem_pool);
736 
737 			icp_adf_transReleaseHandle(
738 			    pCompressionService->trans_handle_compression_tx);
739 
740 			icp_adf_transReleaseHandle(
741 			    pCompressionService->trans_handle_compression_rx);
742 			LAC_OS_FREE(instance_name);
743 			return CPA_STATUS_RESOURCE;
744 		}
745 
746 		memset(pCompressionService->debug_file,
747 		       0,
748 		       sizeof(debug_file_info_t));
749 		pCompressionService->debug_file->name = instance_name;
750 		pCompressionService->debug_file->seq_read =
751 		    SalCtrl_CompresionDebug;
752 		pCompressionService->debug_file->private_data =
753 		    pCompressionService;
754 		pCompressionService->debug_file->parent =
755 		    pCompressionService->generic_service_info.debug_parent_dir;
756 
757 		status = icp_adf_debugAddFile(device,
758 					      pCompressionService->debug_file);
759 		if (CPA_STATUS_SUCCESS != status) {
760 			Lac_MemPoolDestroy(
761 			    pCompressionService->compression_mem_pool);
762 
763 			icp_adf_transReleaseHandle(
764 			    pCompressionService->trans_handle_compression_tx);
765 
766 			icp_adf_transReleaseHandle(
767 			    pCompressionService->trans_handle_compression_rx);
768 			LAC_OS_FREE(instance_name);
769 			LAC_OS_FREE(pCompressionService->debug_file);
770 			return status;
771 		}
772 	}
773 	pCompressionService->generic_service_info.stats = pStatsCollection;
774 	pCompressionService->generic_service_info.state =
775 	    SAL_SERVICE_STATE_INITIALIZED;
776 
777 	return status;
778 }
779 
780 CpaStatus
781 SalCtrl_CompressionStart(icp_accel_dev_t *device, sal_service_t *service)
782 {
783 	CpaStatus status = CPA_STATUS_SUCCESS;
784 
785 	sal_compression_service_t *pCompressionService =
786 	    (sal_compression_service_t *)service;
787 
788 	if (SAL_SERVICE_STATE_INITIALIZED !=
789 	    pCompressionService->generic_service_info.state) {
790 		QAT_UTILS_LOG("Not in the correct state to call start.\n");
791 		return CPA_STATUS_FAIL;
792 	}
793 	/**************************************************************/
794 	/* Obtain Extended Features. I.e. Compress And Verify         */
795 	/**************************************************************/
796 	pCompressionService->generic_service_info.dcExtendedFeatures =
797 	    device->dcExtendedFeatures;
798 	pCompressionService->generic_service_info.state =
799 	    SAL_SERVICE_STATE_RUNNING;
800 
801 	return status;
802 }
803 
804 CpaStatus
805 SalCtrl_CompressionStop(icp_accel_dev_t *device, sal_service_t *service)
806 {
807 	sal_compression_service_t *pCompressionService =
808 	    (sal_compression_service_t *)service;
809 
810 	if (SAL_SERVICE_STATE_RUNNING !=
811 	    pCompressionService->generic_service_info.state) {
812 		QAT_UTILS_LOG("Not in the correct state to call stop.\n");
813 		return CPA_STATUS_FAIL;
814 	}
815 
816 	if (icp_adf_is_dev_in_reset(device)) {
817 		pCompressionService->generic_service_info.state =
818 		    SAL_SERVICE_STATE_RESTARTING;
819 		return CPA_STATUS_SUCCESS;
820 	}
821 
822 	pCompressionService->generic_service_info.state =
823 	    SAL_SERVICE_STATE_SHUTTING_DOWN;
824 	return CPA_STATUS_RETRY;
825 }
826 
827 CpaStatus
828 SalCtrl_CompressionShutdown(icp_accel_dev_t *device, sal_service_t *service)
829 {
830 	CpaStatus status = CPA_STATUS_SUCCESS;
831 
832 	sal_compression_service_t *pCompressionService =
833 	    (sal_compression_service_t *)service;
834 	sal_statistics_collection_t *pStatsCollection =
835 	    (sal_statistics_collection_t *)device->pQatStats;
836 
837 	if ((SAL_SERVICE_STATE_INITIALIZED !=
838 	     pCompressionService->generic_service_info.state) &&
839 	    (SAL_SERVICE_STATE_SHUTTING_DOWN !=
840 	     pCompressionService->generic_service_info.state) &&
841 	    (SAL_SERVICE_STATE_RESTARTING !=
842 	     pCompressionService->generic_service_info.state)) {
843 		QAT_UTILS_LOG("Not in the correct state to call shutdown.\n");
844 		return CPA_STATUS_FAIL;
845 	}
846 
847 	Lac_MemPoolDestroy(pCompressionService->compression_mem_pool);
848 
849 	status = icp_adf_transReleaseHandle(
850 	    pCompressionService->trans_handle_compression_tx);
851 	LAC_CHECK_STATUS(status);
852 
853 	status = icp_adf_transReleaseHandle(
854 	    pCompressionService->trans_handle_compression_rx);
855 	LAC_CHECK_STATUS(status);
856 
857 	if (CPA_TRUE == pStatsCollection->bDcStatsEnabled) {
858 		/* Clean stats */
859 		if (NULL != pCompressionService->debug_file) {
860 			icp_adf_debugRemoveFile(
861 			    pCompressionService->debug_file);
862 			LAC_OS_FREE(pCompressionService->debug_file->name);
863 			LAC_OS_FREE(pCompressionService->debug_file);
864 			pCompressionService->debug_file = NULL;
865 		}
866 	}
867 	pCompressionService->generic_service_info.stats = NULL;
868 	dcStatsFree(pCompressionService);
869 
870 	if (icp_adf_is_dev_in_reset(device)) {
871 		pCompressionService->generic_service_info.state =
872 		    SAL_SERVICE_STATE_RESTARTING;
873 		return CPA_STATUS_SUCCESS;
874 	}
875 	pCompressionService->generic_service_info.state =
876 	    SAL_SERVICE_STATE_SHUTDOWN;
877 	return status;
878 }
879 
880 CpaStatus
881 cpaDcGetStatusText(const CpaInstanceHandle dcInstance,
882 		   const CpaStatus errStatus,
883 		   Cpa8S *pStatusText)
884 {
885 	CpaStatus status = CPA_STATUS_SUCCESS;
886 
887 	LAC_CHECK_NULL_PARAM(pStatusText);
888 
889 	switch (errStatus) {
890 	case CPA_STATUS_SUCCESS:
891 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_SUCCESS);
892 		break;
893 	case CPA_STATUS_FAIL:
894 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_FAIL);
895 		break;
896 	case CPA_STATUS_RETRY:
897 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_RETRY);
898 		break;
899 	case CPA_STATUS_RESOURCE:
900 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_RESOURCE);
901 		break;
902 	case CPA_STATUS_INVALID_PARAM:
903 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_INVALID_PARAM);
904 		break;
905 	case CPA_STATUS_FATAL:
906 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_FATAL);
907 		break;
908 	case CPA_STATUS_UNSUPPORTED:
909 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_UNSUPPORTED);
910 		break;
911 	default:
912 		status = CPA_STATUS_INVALID_PARAM;
913 		break;
914 	}
915 
916 	return status;
917 }
918 
919 CpaStatus
920 cpaDcGetNumIntermediateBuffers(CpaInstanceHandle dcInstance,
921 			       Cpa16U *pNumBuffers)
922 {
923 	CpaInstanceHandle insHandle = NULL;
924 	sal_compression_service_t *pService = NULL;
925 
926 	if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
927 		insHandle = dcGetFirstHandle();
928 	} else {
929 		insHandle = dcInstance;
930 	}
931 
932 	LAC_CHECK_NULL_PARAM(insHandle);
933 	LAC_CHECK_NULL_PARAM(pNumBuffers);
934 
935 	pService = (sal_compression_service_t *)insHandle;
936 	*pNumBuffers = pService->numInterBuffs;
937 
938 	return CPA_STATUS_SUCCESS;
939 }
940 
941 CpaStatus
942 cpaDcStartInstance(CpaInstanceHandle instanceHandle,
943 		   Cpa16U numBuffers,
944 		   CpaBufferList **pIntermediateBufferPtrsArray)
945 {
946 	icp_qat_addr_width_t *pInterBuffPtrsArray = NULL;
947 	icp_qat_addr_width_t pArrayBufferListDescPhyAddr = 0;
948 	icp_qat_addr_width_t bufListDescPhyAddr;
949 	icp_qat_addr_width_t bufListAlignedPhyAddr;
950 	CpaFlatBuffer *pClientCurrFlatBuffer = NULL;
951 	icp_buffer_list_desc_t *pBufferListDesc = NULL;
952 	icp_flat_buffer_desc_t *pCurrFlatBufDesc = NULL;
953 	CpaInstanceInfo2 info = { 0 };
954 	icp_accel_dev_t *dev = NULL;
955 	CpaStatus status = CPA_STATUS_SUCCESS;
956 	sal_compression_service_t *pService = NULL;
957 	CpaInstanceHandle insHandle = NULL;
958 	Cpa16U bufferIndex = 0;
959 	Cpa32U numFlatBuffers = 0;
960 	Cpa64U clientListSize = 0;
961 	CpaBufferList *pClientCurrentIntermediateBuffer = NULL;
962 	Cpa32U bufferIndex2 = 0;
963 	CpaBufferList **pTempIntermediateBufferPtrsArray;
964 	Cpa64U lastClientListSize = 0;
965 
966 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
967 		insHandle = dcGetFirstHandle();
968 	} else {
969 		insHandle = instanceHandle;
970 	}
971 	LAC_CHECK_NULL_PARAM(insHandle);
972 
973 	status = cpaDcInstanceGetInfo2(insHandle, &info);
974 	if (CPA_STATUS_SUCCESS != status) {
975 		QAT_UTILS_LOG("Can not get instance info.\n");
976 		return status;
977 	}
978 
979 	dev = icp_adf_getAccelDevByAccelId(info.physInstId.packageId);
980 	if (NULL == dev) {
981 		QAT_UTILS_LOG("Can not find device for the instance\n");
982 		return CPA_STATUS_FAIL;
983 	}
984 
985 	if (NULL == pIntermediateBufferPtrsArray) {
986 		/* Increment dev ref counter and return - DRAM is not used */
987 		icp_qa_dev_get(dev);
988 		return CPA_STATUS_SUCCESS;
989 	}
990 
991 	if (0 == numBuffers) {
992 		/* Increment dev ref counter and return - DRAM is not used */
993 		icp_qa_dev_get(dev);
994 		return CPA_STATUS_SUCCESS;
995 	}
996 
997 	pService = (sal_compression_service_t *)insHandle;
998 
999 	LAC_CHECK_NULL_PARAM(insHandle);
1000 
1001 	if ((numBuffers > 0) && (NULL == pIntermediateBufferPtrsArray)) {
1002 		QAT_UTILS_LOG("Invalid Intermediate Buffers Array pointer\n");
1003 		return CPA_STATUS_INVALID_PARAM;
1004 	}
1005 
1006 	/* Check number of intermediate buffers allocated by user */
1007 	if ((pService->numInterBuffs != numBuffers)) {
1008 		QAT_UTILS_LOG("Invalid number of buffers\n");
1009 		return CPA_STATUS_INVALID_PARAM;
1010 	}
1011 
1012 	pTempIntermediateBufferPtrsArray = pIntermediateBufferPtrsArray;
1013 	for (bufferIndex = 0; bufferIndex < numBuffers; bufferIndex++) {
1014 		if (NULL == *pTempIntermediateBufferPtrsArray) {
1015 			QAT_UTILS_LOG(
1016 			    "Intermediate Buffer - Invalid Buffer List pointer\n");
1017 			return CPA_STATUS_INVALID_PARAM;
1018 		}
1019 
1020 		if (NULL == (*pTempIntermediateBufferPtrsArray)->pBuffers) {
1021 			QAT_UTILS_LOG(
1022 			    "Intermediate Buffer - Invalid Flat Buffer descriptor pointer\n");
1023 			return CPA_STATUS_INVALID_PARAM;
1024 		}
1025 
1026 		if (NULL ==
1027 		    (*pTempIntermediateBufferPtrsArray)->pPrivateMetaData) {
1028 			QAT_UTILS_LOG(
1029 			    "Intermediate Buffer - Invalid Private MetaData descriptor pointer\n");
1030 			return CPA_STATUS_INVALID_PARAM;
1031 		}
1032 
1033 		clientListSize = 0;
1034 		for (bufferIndex2 = 0; bufferIndex2 <
1035 		     (*pTempIntermediateBufferPtrsArray)->numBuffers;
1036 		     bufferIndex2++) {
1037 
1038 			if ((0 !=
1039 			     (*pTempIntermediateBufferPtrsArray)
1040 				 ->pBuffers[bufferIndex2]
1041 				 .dataLenInBytes) &&
1042 			    NULL ==
1043 				(*pTempIntermediateBufferPtrsArray)
1044 				    ->pBuffers[bufferIndex2]
1045 				    .pData) {
1046 				QAT_UTILS_LOG(
1047 				    "Intermediate Buffer - Invalid Flat Buffer pointer\n");
1048 				return CPA_STATUS_INVALID_PARAM;
1049 			}
1050 
1051 			clientListSize += (*pTempIntermediateBufferPtrsArray)
1052 					      ->pBuffers[bufferIndex2]
1053 					      .dataLenInBytes;
1054 		}
1055 
1056 		if (bufferIndex != 0) {
1057 			if (lastClientListSize != clientListSize) {
1058 				QAT_UTILS_LOG(
1059 				    "SGLs have to be of the same size.\n");
1060 				return CPA_STATUS_INVALID_PARAM;
1061 			}
1062 		} else {
1063 			lastClientListSize = clientListSize;
1064 		}
1065 		pTempIntermediateBufferPtrsArray++;
1066 	}
1067 
1068 	/* Allocate array of physical pointers to icp_buffer_list_desc_t */
1069 	status = LAC_OS_CAMALLOC(&pInterBuffPtrsArray,
1070 				 (numBuffers * sizeof(icp_qat_addr_width_t)),
1071 				 LAC_64BYTE_ALIGNMENT,
1072 				 pService->nodeAffinity);
1073 	if (CPA_STATUS_SUCCESS != status) {
1074 		QAT_UTILS_LOG("Can not allocate Intermediate Buffers array.\n");
1075 		return status;
1076 	}
1077 
1078 	/* Get physical address of the intermediate buffer pointers array */
1079 	pArrayBufferListDescPhyAddr = LAC_MEM_CAST_PTR_TO_UINT64(
1080 	    LAC_OS_VIRT_TO_PHYS_INTERNAL(pInterBuffPtrsArray));
1081 
1082 	pService->pInterBuffPtrsArray = pInterBuffPtrsArray;
1083 	pService->pInterBuffPtrsArrayPhyAddr = pArrayBufferListDescPhyAddr;
1084 
1085 	/* Get the full size of the buffer list */
1086 	/* Assumption: all the SGLs allocated by the user have the same size */
1087 	clientListSize = 0;
1088 	for (bufferIndex = 0;
1089 	     bufferIndex < (*pIntermediateBufferPtrsArray)->numBuffers;
1090 	     bufferIndex++) {
1091 		clientListSize += ((*pIntermediateBufferPtrsArray)
1092 				       ->pBuffers[bufferIndex]
1093 				       .dataLenInBytes);
1094 	}
1095 	pService->minInterBuffSizeInBytes = clientListSize;
1096 
1097 	for (bufferIndex = 0; bufferIndex < numBuffers; bufferIndex++) {
1098 
1099 		/* Get pointer to the client Intermediate Buffer List
1100 		 * (CpaBufferList) */
1101 		pClientCurrentIntermediateBuffer =
1102 		    *pIntermediateBufferPtrsArray;
1103 
1104 		/* Get number of flat buffers in the buffer list */
1105 		numFlatBuffers = pClientCurrentIntermediateBuffer->numBuffers;
1106 
1107 		/* Get pointer to the client array of CpaFlatBuffers */
1108 		pClientCurrFlatBuffer =
1109 		    pClientCurrentIntermediateBuffer->pBuffers;
1110 
1111 		/* Calculate Physical address of current private SGL */
1112 		bufListDescPhyAddr = LAC_OS_VIRT_TO_PHYS_EXTERNAL(
1113 		    (*pService),
1114 		    pClientCurrentIntermediateBuffer->pPrivateMetaData);
1115 		if (bufListDescPhyAddr == 0) {
1116 			QAT_UTILS_LOG(
1117 			    "Unable to get the physical address of the metadata.\n");
1118 			return CPA_STATUS_FAIL;
1119 		}
1120 
1121 		/* Align SGL physical address */
1122 		bufListAlignedPhyAddr =
1123 		    LAC_ALIGN_POW2_ROUNDUP(bufListDescPhyAddr,
1124 					   ICP_DESCRIPTOR_ALIGNMENT_BYTES);
1125 
1126 		/* Set physical address of the Intermediate Buffer SGL in the
1127 		 * SGLs array
1128 		 */
1129 		*pInterBuffPtrsArray =
1130 		    LAC_MEM_CAST_PTR_TO_UINT64(bufListAlignedPhyAddr);
1131 
1132 		/* Calculate (virtual) offset to the buffer list descriptor */
1133 		pBufferListDesc =
1134 		    (icp_buffer_list_desc_t
1135 			 *)((LAC_ARCH_UINT)pClientCurrentIntermediateBuffer
1136 				->pPrivateMetaData +
1137 			    (LAC_ARCH_UINT)(bufListAlignedPhyAddr -
1138 					    bufListDescPhyAddr));
1139 
1140 		/* Set number of flat buffers in the physical Buffer List
1141 		 * descriptor */
1142 		pBufferListDesc->numBuffers = numFlatBuffers;
1143 
1144 		/* Go past the Buffer List descriptor to the list of buffer
1145 		 * descriptors
1146 		 */
1147 		pCurrFlatBufDesc =
1148 		    (icp_flat_buffer_desc_t *)((pBufferListDesc->phyBuffers));
1149 
1150 		/* Loop for each flat buffer in the SGL */
1151 		while (0 != numFlatBuffers) {
1152 			/* Set length of the current flat buffer */
1153 			pCurrFlatBufDesc->dataLenInBytes =
1154 			    pClientCurrFlatBuffer->dataLenInBytes;
1155 
1156 			/* Set physical address of the flat buffer */
1157 			pCurrFlatBufDesc->phyBuffer =
1158 			    LAC_MEM_CAST_PTR_TO_UINT64(
1159 				LAC_OS_VIRT_TO_PHYS_EXTERNAL(
1160 				    (*pService), pClientCurrFlatBuffer->pData));
1161 
1162 			if (pCurrFlatBufDesc->phyBuffer == 0) {
1163 				QAT_UTILS_LOG(
1164 				    "Unable to get the physical address of the flat buffer.\n");
1165 				return CPA_STATUS_FAIL;
1166 			}
1167 
1168 			pCurrFlatBufDesc++;
1169 			pClientCurrFlatBuffer++;
1170 			numFlatBuffers--;
1171 		}
1172 		pIntermediateBufferPtrsArray++;
1173 		pInterBuffPtrsArray++;
1174 	}
1175 
1176 	pService->generic_service_info.isInstanceStarted = CPA_TRUE;
1177 
1178 	/* Increment dev ref counter */
1179 	icp_qa_dev_get(dev);
1180 	return CPA_STATUS_SUCCESS;
1181 }
1182 
1183 CpaStatus
1184 cpaDcStopInstance(CpaInstanceHandle instanceHandle)
1185 {
1186 	CpaInstanceHandle insHandle = NULL;
1187 	CpaInstanceInfo2 info = { 0 };
1188 	icp_accel_dev_t *dev = NULL;
1189 	CpaStatus status = CPA_STATUS_SUCCESS;
1190 	sal_compression_service_t *pService = NULL;
1191 
1192 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
1193 		insHandle = dcGetFirstHandle();
1194 	} else {
1195 		insHandle = instanceHandle;
1196 	}
1197 
1198 	LAC_CHECK_NULL_PARAM(insHandle);
1199 	pService = (sal_compression_service_t *)insHandle;
1200 
1201 	/* Free Intermediate Buffer Pointers Array */
1202 	if (pService->pInterBuffPtrsArray != NULL) {
1203 		LAC_OS_CAFREE(pService->pInterBuffPtrsArray);
1204 		pService->pInterBuffPtrsArray = 0;
1205 	}
1206 
1207 	pService->pInterBuffPtrsArrayPhyAddr = 0;
1208 
1209 	status = cpaDcInstanceGetInfo2(insHandle, &info);
1210 	if (CPA_STATUS_SUCCESS != status) {
1211 		QAT_UTILS_LOG("Can not get instance info.\n");
1212 		return status;
1213 	}
1214 	dev = icp_adf_getAccelDevByAccelId(info.physInstId.packageId);
1215 	if (NULL == dev) {
1216 		QAT_UTILS_LOG("Can not find device for the instance.\n");
1217 		return CPA_STATUS_FAIL;
1218 	}
1219 
1220 	pService->generic_service_info.isInstanceStarted = CPA_FALSE;
1221 
1222 	/* Decrement dev ref counter */
1223 	icp_qa_dev_put(dev);
1224 	return CPA_STATUS_SUCCESS;
1225 }
1226 
1227 CpaStatus
1228 cpaDcGetNumInstances(Cpa16U *pNumInstances)
1229 {
1230 	CpaStatus status = CPA_STATUS_SUCCESS;
1231 	icp_accel_dev_t **pAdfInsts = NULL;
1232 	icp_accel_dev_t *dev_addr = NULL;
1233 	sal_t *base_addr = NULL;
1234 	sal_list_t *list_temp = NULL;
1235 	Cpa16U num_accel_dev = 0;
1236 	Cpa16U num = 0;
1237 	Cpa16U i = 0;
1238 
1239 	LAC_CHECK_NULL_PARAM(pNumInstances);
1240 
1241 	/* Get the number of accel_dev in the system */
1242 	status = icp_amgr_getNumInstances(&num_accel_dev);
1243 	LAC_CHECK_STATUS(status);
1244 
1245 	/* Allocate memory to store addr of accel_devs */
1246 	pAdfInsts =
1247 	    malloc(num_accel_dev * sizeof(icp_accel_dev_t *), M_QAT, M_WAITOK);
1248 	num_accel_dev = 0;
1249 
1250 	/* Get ADF to return accel_devs with dc enabled */
1251 	status = icp_amgr_getAllAccelDevByCapabilities(
1252 	    ICP_ACCEL_CAPABILITIES_COMPRESSION, pAdfInsts, &num_accel_dev);
1253 	if (CPA_STATUS_SUCCESS == status) {
1254 		for (i = 0; i < num_accel_dev; i++) {
1255 			dev_addr = (icp_accel_dev_t *)pAdfInsts[i];
1256 			if (NULL != dev_addr) {
1257 				base_addr = dev_addr->pSalHandle;
1258 				if (NULL != base_addr) {
1259 					list_temp =
1260 					    base_addr->compression_services;
1261 					while (NULL != list_temp) {
1262 						num++;
1263 						list_temp =
1264 						    SalList_next(list_temp);
1265 					}
1266 				}
1267 			}
1268 		}
1269 
1270 		*pNumInstances = num;
1271 	}
1272 
1273 	free(pAdfInsts, M_QAT);
1274 
1275 	return status;
1276 }
1277 
1278 CpaStatus
1279 cpaDcGetInstances(Cpa16U numInstances, CpaInstanceHandle *dcInstances)
1280 {
1281 	CpaStatus status = CPA_STATUS_SUCCESS;
1282 	icp_accel_dev_t **pAdfInsts = NULL;
1283 	icp_accel_dev_t *dev_addr = NULL;
1284 	sal_t *base_addr = NULL;
1285 	sal_list_t *list_temp = NULL;
1286 	Cpa16U num_accel_dev = 0;
1287 	Cpa16U index = 0;
1288 	Cpa16U i = 0;
1289 
1290 	LAC_CHECK_NULL_PARAM(dcInstances);
1291 	if (0 == numInstances) {
1292 		QAT_UTILS_LOG("numInstances is 0.\n");
1293 		return CPA_STATUS_INVALID_PARAM;
1294 	}
1295 
1296 	/* Get the number of accel_dev in the system */
1297 	status = icp_amgr_getNumInstances(&num_accel_dev);
1298 	LAC_CHECK_STATUS(status);
1299 
1300 	/* Allocate memory to store addr of accel_devs */
1301 	pAdfInsts =
1302 	    malloc(num_accel_dev * sizeof(icp_accel_dev_t *), M_QAT, M_WAITOK);
1303 
1304 	num_accel_dev = 0;
1305 	/* Get ADF to return accel_devs with dc enabled */
1306 	status = icp_amgr_getAllAccelDevByCapabilities(
1307 	    ICP_ACCEL_CAPABILITIES_COMPRESSION, pAdfInsts, &num_accel_dev);
1308 
1309 	if (CPA_STATUS_SUCCESS == status) {
1310 		/* First check the number of instances in the system */
1311 		for (i = 0; i < num_accel_dev; i++) {
1312 			dev_addr = (icp_accel_dev_t *)pAdfInsts[i];
1313 			if (NULL != dev_addr) {
1314 				base_addr = dev_addr->pSalHandle;
1315 				if (NULL != base_addr) {
1316 					list_temp =
1317 					    base_addr->compression_services;
1318 					while (NULL != list_temp) {
1319 						if (index >
1320 						    (numInstances - 1)) {
1321 							break;
1322 						}
1323 
1324 						dcInstances[index] =
1325 						    SalList_getObject(
1326 							list_temp);
1327 						list_temp =
1328 						    SalList_next(list_temp);
1329 						index++;
1330 					}
1331 				}
1332 			}
1333 		}
1334 
1335 		if (numInstances > index) {
1336 			QAT_UTILS_LOG("Only %d dc instances available.\n",
1337 				      index);
1338 			status = CPA_STATUS_RESOURCE;
1339 		}
1340 	}
1341 
1342 	if (CPA_STATUS_SUCCESS == status) {
1343 		index = 0;
1344 		for (i = 0; i < num_accel_dev; i++) {
1345 			dev_addr = (icp_accel_dev_t *)pAdfInsts[i];
1346 			/* Note dev_addr cannot be NULL here as numInstances=0
1347 			   is not valid and if dev_addr=NULL then index=0 (which
1348 			   is less than numInstances and status is set to
1349 			   _RESOURCE
1350 			   above */
1351 			base_addr = dev_addr->pSalHandle;
1352 			if (NULL != base_addr) {
1353 				list_temp = base_addr->compression_services;
1354 				while (NULL != list_temp) {
1355 					if (index > (numInstances - 1)) {
1356 						break;
1357 					}
1358 
1359 					dcInstances[index] =
1360 					    SalList_getObject(list_temp);
1361 					list_temp = SalList_next(list_temp);
1362 					index++;
1363 				}
1364 			}
1365 		}
1366 	}
1367 
1368 	free(pAdfInsts, M_QAT);
1369 
1370 	return status;
1371 }
1372 
1373 CpaStatus
1374 cpaDcInstanceGetInfo2(const CpaInstanceHandle instanceHandle,
1375 		      CpaInstanceInfo2 *pInstanceInfo2)
1376 {
1377 	sal_compression_service_t *pCompressionService = NULL;
1378 	CpaInstanceHandle insHandle = NULL;
1379 	icp_accel_dev_t *dev = NULL;
1380 	CpaStatus status = CPA_STATUS_SUCCESS;
1381 	char keyStr[ADF_CFG_MAX_KEY_LEN_IN_BYTES] = { 0 };
1382 	char valStr[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
1383 	char *section = DYN_SEC;
1384 
1385 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
1386 		insHandle = dcGetFirstHandle();
1387 	} else {
1388 		insHandle = instanceHandle;
1389 	}
1390 
1391 	LAC_CHECK_NULL_PARAM(insHandle);
1392 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1393 	LAC_CHECK_NULL_PARAM(pInstanceInfo2);
1394 
1395 	LAC_OS_BZERO(pInstanceInfo2, sizeof(CpaInstanceInfo2));
1396 	pInstanceInfo2->accelerationServiceType =
1397 	    CPA_ACC_SVC_TYPE_DATA_COMPRESSION;
1398 
1399 	snprintf((char *)pInstanceInfo2->vendorName,
1400 		 CPA_INST_VENDOR_NAME_SIZE,
1401 		 "%s",
1402 		 SAL_INFO2_VENDOR_NAME);
1403 	pInstanceInfo2->vendorName[CPA_INST_VENDOR_NAME_SIZE - 1] = '\0';
1404 
1405 	snprintf((char *)pInstanceInfo2->swVersion,
1406 		 CPA_INST_SW_VERSION_SIZE,
1407 		 "Version %d.%d",
1408 		 SAL_INFO2_DRIVER_SW_VERSION_MAJ_NUMBER,
1409 		 SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER);
1410 	pInstanceInfo2->swVersion[CPA_INST_SW_VERSION_SIZE - 1] = '\0';
1411 
1412 	/* Note we can safely read the contents of the compression service
1413 	   instance
1414 	   here because icp_amgr_getAccelDevByCapabilities() only returns devs
1415 	   that have started */
1416 	pCompressionService = (sal_compression_service_t *)insHandle;
1417 	pInstanceInfo2->physInstId.packageId = pCompressionService->pkgID;
1418 	pInstanceInfo2->physInstId.acceleratorId =
1419 	    pCompressionService->acceleratorNum;
1420 	pInstanceInfo2->physInstId.executionEngineId = 0;
1421 	pInstanceInfo2->physInstId.busAddress =
1422 	    icp_adf_get_busAddress(pInstanceInfo2->physInstId.packageId);
1423 
1424 	/* set coreAffinity to zero before use */
1425 	LAC_OS_BZERO(pInstanceInfo2->coreAffinity,
1426 		     sizeof(pInstanceInfo2->coreAffinity));
1427 	CPA_BITMAP_BIT_SET(pInstanceInfo2->coreAffinity,
1428 			   pCompressionService->coreAffinity);
1429 
1430 	pInstanceInfo2->nodeAffinity = pCompressionService->nodeAffinity;
1431 
1432 	if (CPA_TRUE ==
1433 	    pCompressionService->generic_service_info.isInstanceStarted) {
1434 		pInstanceInfo2->operState = CPA_OPER_STATE_UP;
1435 	} else {
1436 		pInstanceInfo2->operState = CPA_OPER_STATE_DOWN;
1437 	}
1438 
1439 	pInstanceInfo2->requiresPhysicallyContiguousMemory = CPA_TRUE;
1440 
1441 	if (SAL_RESP_POLL_CFG_FILE == pCompressionService->isPolled) {
1442 		pInstanceInfo2->isPolled = CPA_TRUE;
1443 	} else {
1444 		pInstanceInfo2->isPolled = CPA_FALSE;
1445 	}
1446 
1447 	pInstanceInfo2->isOffloaded = CPA_TRUE;
1448 	/* Get the instance name and part name from the config file */
1449 	dev = icp_adf_getAccelDevByAccelId(pCompressionService->pkgID);
1450 	if (NULL == dev) {
1451 		QAT_UTILS_LOG("Can not find device for the instance.\n");
1452 		LAC_OS_BZERO(pInstanceInfo2, sizeof(CpaInstanceInfo2));
1453 		return CPA_STATUS_FAIL;
1454 	}
1455 	snprintf((char *)pInstanceInfo2->partName,
1456 		 CPA_INST_PART_NAME_SIZE,
1457 		 SAL_INFO2_PART_NAME,
1458 		 dev->deviceName);
1459 	pInstanceInfo2->partName[CPA_INST_PART_NAME_SIZE - 1] = '\0';
1460 
1461 	if (CPA_FALSE == pCompressionService->generic_service_info.is_dyn) {
1462 		section = icpGetProcessName();
1463 	}
1464 
1465 	status = Sal_StringParsing(
1466 	    "Dc",
1467 	    pCompressionService->generic_service_info.instance,
1468 	    "Name",
1469 	    keyStr);
1470 	LAC_CHECK_STATUS(status);
1471 	status = icp_adf_cfgGetParamValue(dev, section, keyStr, valStr);
1472 	LAC_CHECK_STATUS(status);
1473 	strncpy((char *)pInstanceInfo2->instName,
1474 		valStr,
1475 		sizeof(pInstanceInfo2->instName) - 1);
1476 	pInstanceInfo2->instName[CPA_INST_NAME_SIZE - 1] = '\0';
1477 
1478 #if __GNUC__ >= 7
1479 #pragma GCC diagnostic push
1480 #pragma GCC diagnostic ignored "-Wformat-truncation"
1481 #endif
1482 	snprintf((char *)pInstanceInfo2->instID,
1483 		 CPA_INST_ID_SIZE,
1484 		 "%s_%s",
1485 		 section,
1486 		 valStr);
1487 #if __GNUC__ >= 7
1488 #pragma GCC diagnostic pop
1489 #endif
1490 
1491 	return CPA_STATUS_SUCCESS;
1492 }
1493 
1494 CpaStatus
1495 cpaDcQueryCapabilities(CpaInstanceHandle dcInstance,
1496 		       CpaDcInstanceCapabilities *pInstanceCapabilities)
1497 {
1498 	CpaInstanceHandle insHandle = NULL;
1499 	sal_compression_service_t *pService = NULL;
1500 	Cpa32U capabilitiesMask = 0;
1501 	dc_extd_ftrs_t *pExtendedFtrs = NULL;
1502 
1503 	if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1504 		insHandle = dcGetFirstHandle();
1505 		if (NULL == insHandle) {
1506 			QAT_UTILS_LOG("Can not get the instance.\n");
1507 			return CPA_STATUS_FAIL;
1508 		}
1509 	} else {
1510 		insHandle = dcInstance;
1511 	}
1512 
1513 	pService = (sal_compression_service_t *)insHandle;
1514 
1515 	LAC_CHECK_NULL_PARAM(insHandle);
1516 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1517 	LAC_CHECK_NULL_PARAM(pInstanceCapabilities);
1518 
1519 	memset(pInstanceCapabilities, 0, sizeof(CpaDcInstanceCapabilities));
1520 
1521 	capabilitiesMask = pService->generic_service_info.capabilitiesMask;
1522 
1523 	/* Set compression capabilities */
1524 	if (capabilitiesMask & ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY) {
1525 		pInstanceCapabilities->integrityCrcs = CPA_TRUE;
1526 	}
1527 
1528 	pInstanceCapabilities->endOfLastBlock = CPA_TRUE;
1529 	pInstanceCapabilities->statefulDeflateCompression = CPA_FALSE;
1530 	pInstanceCapabilities->statefulDeflateDecompression = CPA_TRUE;
1531 	pInstanceCapabilities->statelessDeflateCompression = CPA_TRUE;
1532 	pInstanceCapabilities->statelessDeflateDecompression = CPA_TRUE;
1533 	pInstanceCapabilities->checksumCRC32 = CPA_TRUE;
1534 	pInstanceCapabilities->checksumAdler32 = CPA_TRUE;
1535 	pInstanceCapabilities->dynamicHuffman = CPA_TRUE;
1536 	pInstanceCapabilities->precompiledHuffman = CPA_FALSE;
1537 	pInstanceCapabilities->dynamicHuffmanBufferReq = CPA_TRUE;
1538 	pInstanceCapabilities->autoSelectBestHuffmanTree = CPA_TRUE;
1539 
1540 	pInstanceCapabilities->validWindowSizeMaskCompression =
1541 	    pService->comp_device_data.windowSizeMask;
1542 	pInstanceCapabilities->validWindowSizeMaskDecompression =
1543 	    pService->comp_device_data.windowSizeMask;
1544 	pExtendedFtrs = (dc_extd_ftrs_t *)&(
1545 	    ((sal_service_t *)insHandle)->dcExtendedFeatures);
1546 	pInstanceCapabilities->batchAndPack = CPA_FALSE;
1547 	pInstanceCapabilities->compressAndVerify =
1548 	    (CpaBoolean)pExtendedFtrs->is_cnv;
1549 	pInstanceCapabilities->compressAndVerifyStrict = CPA_TRUE;
1550 	pInstanceCapabilities->compressAndVerifyAndRecover =
1551 	    (CpaBoolean)pExtendedFtrs->is_cnvnr;
1552 	return CPA_STATUS_SUCCESS;
1553 }
1554 
1555 CpaStatus
1556 cpaDcSetAddressTranslation(const CpaInstanceHandle instanceHandle,
1557 			   CpaVirtualToPhysical virtual2Physical)
1558 {
1559 	sal_service_t *pService = NULL;
1560 	CpaInstanceHandle insHandle = NULL;
1561 
1562 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
1563 		insHandle = dcGetFirstHandle();
1564 	} else {
1565 		insHandle = instanceHandle;
1566 	}
1567 
1568 	LAC_CHECK_NULL_PARAM(insHandle);
1569 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1570 	LAC_CHECK_NULL_PARAM(virtual2Physical);
1571 
1572 	pService = (sal_service_t *)insHandle;
1573 
1574 	pService->virt2PhysClient = virtual2Physical;
1575 
1576 	return CPA_STATUS_SUCCESS;
1577 }
1578 
1579 /**
1580  ******************************************************************************
1581  * @ingroup cpaDcCommon
1582  * Data compression specific polling function which polls a DC instance.
1583  *****************************************************************************/
1584 
1585 CpaStatus
1586 icp_sal_DcPollInstance(CpaInstanceHandle instanceHandle_in,
1587 		       Cpa32U response_quota)
1588 {
1589 	CpaStatus status = CPA_STATUS_SUCCESS;
1590 	sal_compression_service_t *dc_handle = NULL;
1591 	sal_service_t *gen_handle = NULL;
1592 	icp_comms_trans_handle trans_hndTable[DC_NUM_RX_RINGS];
1593 
1594 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
1595 		dc_handle = (sal_compression_service_t *)dcGetFirstHandle();
1596 	} else {
1597 		dc_handle = (sal_compression_service_t *)instanceHandle_in;
1598 	}
1599 
1600 	LAC_CHECK_NULL_PARAM(dc_handle);
1601 	SAL_RUNNING_CHECK(dc_handle);
1602 
1603 	gen_handle = &(dc_handle->generic_service_info);
1604 	if (SAL_SERVICE_TYPE_COMPRESSION != gen_handle->type) {
1605 		QAT_UTILS_LOG("Instance handle type is incorrect.\n");
1606 		return CPA_STATUS_FAIL;
1607 	}
1608 
1609 	/*
1610 	 * From the instanceHandle we must get the trans_handle and send
1611 	 * down to adf for polling.
1612 	 * Populate our trans handle table with the appropriate handles.
1613 	 */
1614 	trans_hndTable[0] = dc_handle->trans_handle_compression_rx;
1615 
1616 	/* Call adf to do the polling. */
1617 	status = icp_adf_pollInstance(trans_hndTable,
1618 				      DC_NUM_RX_RINGS,
1619 				      response_quota);
1620 	return status;
1621 }
1622 
1623 /**
1624  ******************************************************************************
1625  * @ingroup cpaDcCommon
1626  *****************************************************************************/
1627 CpaStatus
1628 cpaDcInstanceSetNotificationCb(
1629     const CpaInstanceHandle instanceHandle,
1630     const CpaDcInstanceNotificationCbFunc pInstanceNotificationCb,
1631     void *pCallbackTag)
1632 {
1633 	CpaStatus status = CPA_STATUS_SUCCESS;
1634 	sal_service_t *gen_handle = instanceHandle;
1635 
1636 	LAC_CHECK_NULL_PARAM(gen_handle);
1637 	gen_handle->notification_cb = pInstanceNotificationCb;
1638 	gen_handle->cb_tag = pCallbackTag;
1639 	return status;
1640 }
1641 
1642 CpaInstanceHandle
1643 dcGetFirstHandle(void)
1644 {
1645 	CpaStatus status = CPA_STATUS_SUCCESS;
1646 	static icp_accel_dev_t *adfInsts[ADF_MAX_DEVICES] = { 0 };
1647 	CpaInstanceHandle dcInst = NULL;
1648 	icp_accel_dev_t *dev_addr = NULL;
1649 	sal_t *base_addr = NULL;
1650 	sal_list_t *list_temp = NULL;
1651 	Cpa16U i, num_dc = 0;
1652 
1653 	/* Only need 1 dev with compression enabled - so check all devices */
1654 	status = icp_amgr_getAllAccelDevByCapabilities(
1655 	    ICP_ACCEL_CAPABILITIES_COMPRESSION, adfInsts, &num_dc);
1656 	if ((0 == num_dc) || (CPA_STATUS_SUCCESS != status)) {
1657 		QAT_UTILS_LOG(
1658 		    "No compression devices enabled in the system.\n");
1659 		return dcInst;
1660 	}
1661 
1662 	for (i = 0; i < num_dc; i++) {
1663 		dev_addr = (icp_accel_dev_t *)adfInsts[i];
1664 		if (NULL != dev_addr) {
1665 			base_addr = dev_addr->pSalHandle;
1666 			if (NULL != base_addr) {
1667 				list_temp = base_addr->compression_services;
1668 				if (NULL != list_temp) {
1669 					dcInst = SalList_getObject(list_temp);
1670 					break;
1671 				}
1672 			}
1673 		}
1674 	}
1675 	return dcInst;
1676 }
1677