drivers/infiniband/hw/hns/hns_roce_cmd.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/hns/hns_roce_cmd.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/hns/hns_roce_cmd.c
Extension
.c
Size
7392 bytes
Lines
292
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: implementation source
Status
source 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

msecs_to_jiffies(HNS_ROCE_CMD_TIMEOUT_MSECS))) {
		dev_err_ratelimited(dev, "[cmd] token 0x%x mailbox 0x%x timeout.\n",
				    context->token, mbox_msg->cmd);
		ret = -EBUSY;
		goto out;
	}

	ret = context->result;
	if (ret)
		dev_err_ratelimited(dev, "[cmd] token 0x%x mailbox 0x%x error %d.\n",
				    context->token, mbox_msg->cmd, ret);

out:
	context->busy = 0;
	return ret;
}

static int hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev,
				  struct hns_roce_mbox_msg *mbox_msg)
{
	int ret;

	down(&hr_dev->cmd.event_sem);
	ret = __hns_roce_cmd_mbox_wait(hr_dev, mbox_msg);
	up(&hr_dev->cmd.event_sem);

	return ret;
}

int hns_roce_cmd_mbox(struct hns_roce_dev *hr_dev, u64 in_param, u64 out_param,
		      u8 cmd, unsigned long tag)
{
	struct hns_roce_mbox_msg mbox_msg = {};
	bool is_busy;

	if (hr_dev->hw->chk_mbox_avail)
		if (!hr_dev->hw->chk_mbox_avail(hr_dev, &is_busy))
			return is_busy ? -EBUSY : 0;

	mbox_msg.in_param = in_param;
	mbox_msg.out_param = out_param;
	mbox_msg.cmd = cmd;
	mbox_msg.tag = tag;

	if (hr_dev->cmd.use_events) {
		mbox_msg.event_en = 1;

		return hns_roce_cmd_mbox_wait(hr_dev, &mbox_msg);
	} else {
		mbox_msg.event_en = 0;
		mbox_msg.token = CMD_POLL_TOKEN;

		return hns_roce_cmd_mbox_poll(hr_dev, &mbox_msg);
	}
}

int hns_roce_cmd_init(struct hns_roce_dev *hr_dev)
{
	sema_init(&hr_dev->cmd.poll_sem, 1);
	hr_dev->cmd.use_events = 0;
	hr_dev->cmd.max_cmds = CMD_MAX_NUM;
	hr_dev->cmd.pool = dma_pool_create("hns_roce_cmd", hr_dev->dev,
					   HNS_ROCE_MAILBOX_SIZE,
					   HNS_ROCE_MAILBOX_SIZE, 0);
	if (!hr_dev->cmd.pool)
		return -ENOMEM;

	return 0;
}

void hns_roce_cmd_cleanup(struct hns_roce_dev *hr_dev)
{
	dma_pool_destroy(hr_dev->cmd.pool);
}

int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev)
{
	struct hns_roce_cmdq *hr_cmd = &hr_dev->cmd;
	int i;

	hr_cmd->context =
		kzalloc_objs(*hr_cmd->context, hr_cmd->max_cmds);
	if (!hr_cmd->context) {
		hr_dev->cmd_mod = 0;
		return -ENOMEM;
	}

	for (i = 0; i < hr_cmd->max_cmds; ++i) {
		hr_cmd->context[i].token = i;
		hr_cmd->context[i].next = i + 1;

Annotation

Implementation Notes