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