Exemple #1
0
static int pp_check_ntb(struct ntb_dev *ntb)
{
	u64 pmask;

	if (ntb_db_is_unsafe(ntb)) {
		dev_dbg(&ntb->dev, "Doorbell is unsafe\n");
		if (!unsafe)
			return -EINVAL;
	}

	if (ntb_spad_is_unsafe(ntb)) {
		dev_dbg(&ntb->dev, "Scratchpad is unsafe\n");
		if (!unsafe)
			return -EINVAL;
	}

	pmask = GENMASK_ULL(ntb_peer_port_count(ntb), 0);
	if ((ntb_db_valid_mask(ntb) & pmask) != pmask) {
		dev_err(&ntb->dev, "Unsupported DB configuration\n");
		return -EINVAL;
	}

	if (ntb_spad_count(ntb) < 1 && ntb_msg_count(ntb) < 1) {
		dev_err(&ntb->dev, "Scratchpads and messages unsupported\n");
		return -EINVAL;
	} else if (ntb_spad_count(ntb) < 1) {
		dev_dbg(&ntb->dev, "Scratchpads unsupported\n");
	} else if (ntb_msg_count(ntb) < 1) {
		dev_dbg(&ntb->dev, "Messages unsupported\n");
	}

	return 0;
}
Exemple #2
0
static int perf_probe(struct ntb_client *client, struct ntb_dev *ntb)
{
	struct pci_dev *pdev = ntb->pdev;
	struct perf_ctx *perf;
	int node;
	int rc = 0;

	if (ntb_spad_count(ntb) < MAX_SPAD) {
		dev_err(&ntb->dev, "Not enough scratch pad registers for %s",
			DRIVER_NAME);
		return -EIO;
	}

	node = dev_to_node(&pdev->dev);

	perf = kzalloc_node(sizeof(*perf), GFP_KERNEL, node);
	if (!perf) {
		rc = -ENOMEM;
		goto err_perf;
	}

	perf->ntb = ntb;
	perf->perf_threads = 1;
	atomic_set(&perf->tsync, 0);
	mutex_init(&perf->run_mutex);
	spin_lock_init(&perf->db_lock);
	perf_setup_mw(ntb, perf);
	init_waitqueue_head(&perf->link_wq);
	INIT_DELAYED_WORK(&perf->link_work, perf_link_work);

	rc = ntb_set_ctx(ntb, perf, &perf_ops);
	if (rc)
		goto err_ctx;

	perf->link_is_up = false;
	ntb_link_enable(ntb, NTB_SPEED_AUTO, NTB_WIDTH_AUTO);
	ntb_link_event(ntb);

	rc = perf_debugfs_setup(perf);
	if (rc)
		goto err_ctx;

	perf_clear_thread_status(perf);

	return 0;

err_ctx:
	cancel_delayed_work_sync(&perf->link_work);
	kfree(perf);
err_perf:
	return rc;
}
Exemple #3
0
static ssize_t tool_spadfn_read(struct tool_ctx *tc, char __user *ubuf,
				size_t size, loff_t *offp,
				u32 (*spad_read_fn)(struct ntb_dev *, int))
{
	size_t buf_size;
	char *buf;
	ssize_t pos, rc;
	int i, spad_count;

	if (!spad_read_fn)
		return -EINVAL;

	spad_count = ntb_spad_count(tc->ntb);

	/*
	 * We multiply the number of spads by 15 to get the buffer size
	 * this is from 3 for the %d, 10 for the largest hex value
	 * (0x00000000) and 2 for the tab and line feed.
	 */
	buf_size = min_t(size_t, size, spad_count * 15);

	buf = kmalloc(buf_size, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	pos = 0;

	for (i = 0; i < spad_count; ++i) {
		pos += scnprintf(buf + pos, buf_size - pos, "%d\t%#x\n",
				 i, spad_read_fn(tc->ntb, i));
	}

	rc = simple_read_from_buffer(ubuf, size, offp, buf, pos);

	kfree(buf);

	return rc;
}
Exemple #4
0
static int tool_probe(struct ntb_client *self, struct ntb_dev *ntb)
{
	struct tool_ctx *tc;
	int rc;
	int i;

	if (!ntb->ops->mw_set_trans) {
		dev_dbg(&ntb->dev, "need inbound MW based NTB API\n");
		rc = -EINVAL;
		goto err_tc;
	}

	if (ntb_spad_count(ntb) < 1) {
		dev_dbg(&ntb->dev, "no enough scratchpads\n");
		rc = -EINVAL;
		goto err_tc;
	}

	if (ntb_db_is_unsafe(ntb))
		dev_dbg(&ntb->dev, "doorbell is unsafe\n");

	if (ntb_spad_is_unsafe(ntb))
		dev_dbg(&ntb->dev, "scratchpad is unsafe\n");

	if (ntb_peer_port_count(ntb) != NTB_DEF_PEER_CNT)
		dev_warn(&ntb->dev, "multi-port NTB is unsupported\n");

	tc = kzalloc(sizeof(*tc), GFP_KERNEL);
	if (!tc) {
		rc = -ENOMEM;
		goto err_tc;
	}

	tc->ntb = ntb;
	init_waitqueue_head(&tc->link_wq);

	tc->mw_count = min(ntb_peer_mw_count(tc->ntb), MAX_MWS);
	for (i = 0; i < tc->mw_count; i++) {
		rc = tool_init_mw(tc, i);
		if (rc)
			goto err_ctx;
	}

	tool_setup_dbgfs(tc);

	rc = ntb_set_ctx(ntb, tc, &tool_ops);
	if (rc)
		goto err_ctx;

	ntb_link_enable(ntb, NTB_SPEED_AUTO, NTB_WIDTH_AUTO);
	ntb_link_event(ntb);

	return 0;

err_ctx:
	tool_free_mws(tc);
	debugfs_remove_recursive(tc->dbgfs);
	kfree(tc);
err_tc:
	return rc;
}