Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfcaa396 authored by Logan Gunthorpe's avatar Logan Gunthorpe Committed by Jon Mason
Browse files

ntb_tool: Add link status and files to debugfs



In order to more successfully script with ntb_tool it's useful to
have a link file to check the link status so that the script
doesn't use the other files until the link is up.

This commit adds a 'link' file to the debugfs directory which reads
boolean (Y or N) depending on the link status. Writing to the file
change the link state using ntb_link_enable or ntb_link_disable.

A 'link_event' file is also provided so an application can block until
the link changes to the desired state. If the user writes a 1, it will
block until the link is up. If the user writes a 0, it will block until
the link is down.

Signed-off-by: default avatarLogan Gunthorpe <logang@deltatee.com>
Acked-by: default avatarAllen Hubbe <Allen.Hubbe@emc.com>
Signed-off-by: default avatarJon Mason <jdmason@kudzu.us>
parent 717146a2
Loading
Loading
Loading
Loading
+92 −0
Original line number Original line Diff line number Diff line
@@ -59,6 +59,12 @@
 *
 *
 * Eg: check if clearing the doorbell mask generates an interrupt.
 * Eg: check if clearing the doorbell mask generates an interrupt.
 *
 *
 * # Check the link status
 * root@self# cat $DBG_DIR/link
 *
 * # Block until the link is up
 * root@self# echo Y > $DBG_DIR/link_event
 *
 * # Set the doorbell mask
 * # Set the doorbell mask
 * root@self# echo 's 1' > $DBG_DIR/mask
 * root@self# echo 's 1' > $DBG_DIR/mask
 *
 *
@@ -131,6 +137,7 @@ struct tool_mw {
struct tool_ctx {
struct tool_ctx {
	struct ntb_dev *ntb;
	struct ntb_dev *ntb;
	struct dentry *dbgfs;
	struct dentry *dbgfs;
	wait_queue_head_t link_wq;
	int mw_count;
	int mw_count;
	struct tool_mw mws[MAX_MWS];
	struct tool_mw mws[MAX_MWS];
};
};
@@ -159,6 +166,7 @@ static void tool_link_event(void *ctx)
	dev_dbg(&tc->ntb->dev, "link is %s speed %d width %d\n",
	dev_dbg(&tc->ntb->dev, "link is %s speed %d width %d\n",
		up ? "up" : "down", speed, width);
		up ? "up" : "down", speed, width);


	wake_up(&tc->link_wq);
}
}


static void tool_db_event(void *ctx, int vec)
static void tool_db_event(void *ctx, int vec)
@@ -473,6 +481,83 @@ static TOOL_FOPS_RDWR(tool_peer_spad_fops,
		      tool_peer_spad_read,
		      tool_peer_spad_read,
		      tool_peer_spad_write);
		      tool_peer_spad_write);


static ssize_t tool_link_read(struct file *filep, char __user *ubuf,
			      size_t size, loff_t *offp)
{
	struct tool_ctx *tc = filep->private_data;
	char buf[3];

	buf[0] = ntb_link_is_up(tc->ntb, NULL, NULL) ? 'Y' : 'N';
	buf[1] = '\n';
	buf[2] = '\0';

	return simple_read_from_buffer(ubuf, size, offp, buf, 2);
}

static ssize_t tool_link_write(struct file *filep, const char __user *ubuf,
			       size_t size, loff_t *offp)
{
	struct tool_ctx *tc = filep->private_data;
	char buf[32];
	size_t buf_size;
	bool val;
	int rc;

	buf_size = min(size, (sizeof(buf) - 1));
	if (copy_from_user(buf, ubuf, buf_size))
		return -EFAULT;

	buf[buf_size] = '\0';

	rc = strtobool(buf, &val);
	if (rc)
		return rc;

	if (val)
		rc = ntb_link_enable(tc->ntb, NTB_SPEED_AUTO, NTB_WIDTH_AUTO);
	else
		rc = ntb_link_disable(tc->ntb);

	if (rc)
		return rc;

	return size;
}

static TOOL_FOPS_RDWR(tool_link_fops,
		      tool_link_read,
		      tool_link_write);

static ssize_t tool_link_event_write(struct file *filep,
				     const char __user *ubuf,
				     size_t size, loff_t *offp)
{
	struct tool_ctx *tc = filep->private_data;
	char buf[32];
	size_t buf_size;
	bool val;
	int rc;

	buf_size = min(size, (sizeof(buf) - 1));
	if (copy_from_user(buf, ubuf, buf_size))
		return -EFAULT;

	buf[buf_size] = '\0';

	rc = strtobool(buf, &val);
	if (rc)
		return rc;

	if (wait_event_interruptible(tc->link_wq,
		ntb_link_is_up(tc->ntb, NULL, NULL) == val))
		return -ERESTART;

	return size;
}

static TOOL_FOPS_RDWR(tool_link_event_fops,
		      NULL,
		      tool_link_event_write);


static ssize_t tool_mw_read(struct file *filep, char __user *ubuf,
static ssize_t tool_mw_read(struct file *filep, char __user *ubuf,
			    size_t size, loff_t *offp)
			    size_t size, loff_t *offp)
@@ -803,6 +888,12 @@ static void tool_setup_dbgfs(struct tool_ctx *tc)
	debugfs_create_file("peer_spad", S_IRUSR | S_IWUSR, tc->dbgfs,
	debugfs_create_file("peer_spad", S_IRUSR | S_IWUSR, tc->dbgfs,
			    tc, &tool_peer_spad_fops);
			    tc, &tool_peer_spad_fops);


	debugfs_create_file("link", S_IRUSR | S_IWUSR, tc->dbgfs,
			    tc, &tool_link_fops);

	debugfs_create_file("link_event", S_IWUSR, tc->dbgfs,
			    tc, &tool_link_event_fops);

	for (i = 0; i < tc->mw_count; i++) {
	for (i = 0; i < tc->mw_count; i++) {
		char buf[30];
		char buf[30];


@@ -835,6 +926,7 @@ static int tool_probe(struct ntb_client *self, struct ntb_dev *ntb)
	}
	}


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


	tc->mw_count = min(ntb_mw_count(tc->ntb), MAX_MWS);
	tc->mw_count = min(ntb_mw_count(tc->ntb), MAX_MWS);
	for (i = 0; i < tc->mw_count; i++) {
	for (i = 0; i < tc->mw_count; i++) {