net/bluetooth/mgmt_util.c

Source file repositories/reference/linux-study-clean/net/bluetooth/mgmt_util.c

File Facts

System
Linux kernel
Corpus path
net/bluetooth/mgmt_util.c
Extension
.c
Size
9653 bytes
Lines
439
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (cmd->opcode == opcode) {
			mutex_unlock(&hdev->mgmt_pending_lock);
			return cmd;
		}
	}

	mutex_unlock(&hdev->mgmt_pending_lock);

	return NULL;
}

void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove,
			  void (*cb)(struct mgmt_pending_cmd *cmd, void *data),
			  void *data)
{
	struct mgmt_pending_cmd *cmd, *tmp;

	mutex_lock(&hdev->mgmt_pending_lock);

	list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
		if (opcode > 0 && cmd->opcode != opcode)
			continue;

		if (remove)
			list_del(&cmd->list);

		cb(cmd, data);

		if (remove)
			mgmt_pending_free(cmd);
	}

	mutex_unlock(&hdev->mgmt_pending_lock);
}

struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode,
					  struct hci_dev *hdev,
					  void *data, u16 len)
{
	struct mgmt_pending_cmd *cmd;

	cmd = kzalloc_obj(*cmd);
	if (!cmd)
		return NULL;

	cmd->opcode = opcode;
	cmd->hdev = hdev;

	cmd->param = kmemdup(data, len, GFP_KERNEL);
	if (!cmd->param) {
		kfree(cmd);
		return NULL;
	}

	cmd->param_len = len;

	cmd->sk = sk;
	sock_hold(sk);

	return cmd;
}

struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
					  struct hci_dev *hdev,
					  void *data, u16 len)
{
	struct mgmt_pending_cmd *cmd;

	cmd = mgmt_pending_new(sk, opcode, hdev, data, len);
	if (!cmd)
		return NULL;

	mutex_lock(&hdev->mgmt_pending_lock);
	list_add_tail(&cmd->list, &hdev->mgmt_pending);
	mutex_unlock(&hdev->mgmt_pending_lock);

	return cmd;
}

void mgmt_pending_free(struct mgmt_pending_cmd *cmd)
{
	sock_put(cmd->sk);
	kfree(cmd->param);
	kfree(cmd);
}

void mgmt_pending_remove(struct mgmt_pending_cmd *cmd)
{
	mutex_lock(&cmd->hdev->mgmt_pending_lock);
	list_del(&cmd->list);

Annotation

Implementation Notes