drivers/crypto/intel/qat/qat_common/adf_cfg_services.c

Source file repositories/reference/linux-study-clean/drivers/crypto/intel/qat/qat_common/adf_cfg_services.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/intel/qat/qat_common/adf_cfg_services.c
Extension
.c
Size
5140 bytes
Lines
212
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2023 Intel Corporation */

#include <linux/array_size.h>
#include <linux/bitops.h>
#include <linux/export.h>
#include <linux/pci.h>
#include <linux/string.h>
#include "adf_cfg.h"
#include "adf_cfg_common.h"
#include "adf_cfg_services.h"
#include "adf_cfg_strings.h"

static const char *const adf_cfg_services[] = {
	[SVC_ASYM] = ADF_CFG_ASYM,
	[SVC_SYM] = ADF_CFG_SYM,
	[SVC_DC] = ADF_CFG_DC,
	[SVC_DCC] = ADF_CFG_DCC,
	[SVC_DECOMP] = ADF_CFG_DECOMP,
};

/*
 * Ensure that the size of the array matches the number of services,
 * SVC_COUNT, that is used to size the bitmap.
 */
static_assert(ARRAY_SIZE(adf_cfg_services) == SVC_COUNT);

/*
 * Ensure that the maximum number of concurrent services that can be
 * enabled on a device is less than or equal to the number of total
 * supported services.
 */
static_assert(ARRAY_SIZE(adf_cfg_services) >= MAX_NUM_CONCURR_SVC);

/*
 * Ensure that the number of services fit a single unsigned long, as each
 * service is represented by a bit in the mask.
 */
static_assert(BITS_PER_LONG >= SVC_COUNT);

/*
 * Ensure that size of the concatenation of all service strings is smaller
 * than the size of the buffer that will contain them.
 */
static_assert(sizeof(ADF_CFG_SYM ADF_SERVICES_DELIMITER
		     ADF_CFG_ASYM ADF_SERVICES_DELIMITER
		     ADF_CFG_DC ADF_SERVICES_DELIMITER
		     ADF_CFG_DECOMP ADF_SERVICES_DELIMITER
		     ADF_CFG_DCC) < ADF_CFG_MAX_VAL_LEN_IN_BYTES);

static int adf_service_string_to_mask(struct adf_accel_dev *accel_dev, const char *buf,
				      size_t len, unsigned long *out_mask)
{
	struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
	char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { };
	unsigned long mask = 0;
	char *substr, *token;
	int id, num_svc = 0;

	if (len > ADF_CFG_MAX_VAL_LEN_IN_BYTES - 1)
		return -EINVAL;

	strscpy(services, buf, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
	substr = services;

	while ((token = strsep(&substr, ADF_SERVICES_DELIMITER))) {
		id = sysfs_match_string(adf_cfg_services, token);
		if (id < 0)
			return id;

		if (test_and_set_bit(id, &mask))
			return -EINVAL;

		if (num_svc++ == MAX_NUM_CONCURR_SVC)
			return -EINVAL;
	}

	if (hw_data->services_supported && !hw_data->services_supported(mask))
		return -EINVAL;

	*out_mask = mask;

	return 0;
}

static int adf_service_mask_to_string(unsigned long mask, char *buf, size_t len)
{
	int offset = 0;
	int bit;

Annotation

Implementation Notes