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