aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLogan Gunthorpe <logang@deltatee.com>2016-06-20 15:15:10 -0400
committerJon Mason <jdmason@kudzu.us>2016-08-05 10:21:07 -0400
commitbfcaa39652bf64294261415e5fa18ef0445a4d74 (patch)
tree7bfc6fd71823bdf697dc64d3ed51e76c3eae7fea
parent717146a2a8cbf6dbcb8fdf4ae7cddd2d6074161c (diff)
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: Logan Gunthorpe <logang@deltatee.com> Acked-by: Allen Hubbe <Allen.Hubbe@emc.com> Signed-off-by: Jon Mason <jdmason@kudzu.us>
-rw-r--r--drivers/ntb/test/ntb_tool.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/drivers/ntb/test/ntb_tool.c b/drivers/ntb/test/ntb_tool.c
index 1509b4c1f204..61bf2ef87e0e 100644
--- a/drivers/ntb/test/ntb_tool.c
+++ b/drivers/ntb/test/ntb_tool.c
@@ -59,6 +59,12 @@
59 * 59 *
60 * Eg: check if clearing the doorbell mask generates an interrupt. 60 * Eg: check if clearing the doorbell mask generates an interrupt.
61 * 61 *
62 * # Check the link status
63 * root@self# cat $DBG_DIR/link
64 *
65 * # Block until the link is up
66 * root@self# echo Y > $DBG_DIR/link_event
67 *
62 * # Set the doorbell mask 68 * # Set the doorbell mask
63 * root@self# echo 's 1' > $DBG_DIR/mask 69 * root@self# echo 's 1' > $DBG_DIR/mask
64 * 70 *
@@ -131,6 +137,7 @@ struct tool_mw {
131struct tool_ctx { 137struct tool_ctx {
132 struct ntb_dev *ntb; 138 struct ntb_dev *ntb;
133 struct dentry *dbgfs; 139 struct dentry *dbgfs;
140 wait_queue_head_t link_wq;
134 int mw_count; 141 int mw_count;
135 struct tool_mw mws[MAX_MWS]; 142 struct tool_mw mws[MAX_MWS];
136}; 143};
@@ -159,6 +166,7 @@ static void tool_link_event(void *ctx)
159 dev_dbg(&tc->ntb->dev, "link is %s speed %d width %d\n", 166 dev_dbg(&tc->ntb->dev, "link is %s speed %d width %d\n",
160 up ? "up" : "down", speed, width); 167 up ? "up" : "down", speed, width);
161 168
169 wake_up(&tc->link_wq);
162} 170}
163 171
164static void tool_db_event(void *ctx, int vec) 172static void tool_db_event(void *ctx, int vec)
@@ -473,6 +481,83 @@ static TOOL_FOPS_RDWR(tool_peer_spad_fops,
473 tool_peer_spad_read, 481 tool_peer_spad_read,
474 tool_peer_spad_write); 482 tool_peer_spad_write);
475 483
484static ssize_t tool_link_read(struct file *filep, char __user *ubuf,
485 size_t size, loff_t *offp)
486{
487 struct tool_ctx *tc = filep->private_data;
488 char buf[3];
489
490 buf[0] = ntb_link_is_up(tc->ntb, NULL, NULL) ? 'Y' : 'N';
491 buf[1] = '\n';
492 buf[2] = '\0';
493
494 return simple_read_from_buffer(ubuf, size, offp, buf, 2);
495}
496
497static ssize_t tool_link_write(struct file *filep, const char __user *ubuf,
498 size_t size, loff_t *offp)
499{
500 struct tool_ctx *tc = filep->private_data;
501 char buf[32];
502 size_t buf_size;
503 bool val;
504 int rc;
505
506 buf_size = min(size, (sizeof(buf) - 1));
507 if (copy_from_user(buf, ubuf, buf_size))
508 return -EFAULT;
509
510 buf[buf_size] = '\0';
511
512 rc = strtobool(buf, &val);
513 if (rc)
514 return rc;
515
516 if (val)
517 rc = ntb_link_enable(tc->ntb, NTB_SPEED_AUTO, NTB_WIDTH_AUTO);
518 else
519 rc = ntb_link_disable(tc->ntb);
520
521 if (rc)
522 return rc;
523
524 return size;
525}
526
527static TOOL_FOPS_RDWR(tool_link_fops,
528 tool_link_read,
529 tool_link_write);
530
531static ssize_t tool_link_event_write(struct file *filep,
532 const char __user *ubuf,
533 size_t size, loff_t *offp)
534{
535 struct tool_ctx *tc = filep->private_data;
536 char buf[32];
537 size_t buf_size;
538 bool val;
539 int rc;
540
541 buf_size = min(size, (sizeof(buf) - 1));
542 if (copy_from_user(buf, ubuf, buf_size))
543 return -EFAULT;
544
545 buf[buf_size] = '\0';
546
547 rc = strtobool(buf, &val);
548 if (rc)
549 return rc;
550
551 if (wait_event_interruptible(tc->link_wq,
552 ntb_link_is_up(tc->ntb, NULL, NULL) == val))
553 return -ERESTART;
554
555 return size;
556}
557
558static TOOL_FOPS_RDWR(tool_link_event_fops,
559 NULL,
560 tool_link_event_write);
476 561
477static ssize_t tool_mw_read(struct file *filep, char __user *ubuf, 562static ssize_t tool_mw_read(struct file *filep, char __user *ubuf,
478 size_t size, loff_t *offp) 563 size_t size, loff_t *offp)
@@ -803,6 +888,12 @@ static void tool_setup_dbgfs(struct tool_ctx *tc)
803 debugfs_create_file("peer_spad", S_IRUSR | S_IWUSR, tc->dbgfs, 888 debugfs_create_file("peer_spad", S_IRUSR | S_IWUSR, tc->dbgfs,
804 tc, &tool_peer_spad_fops); 889 tc, &tool_peer_spad_fops);
805 890
891 debugfs_create_file("link", S_IRUSR | S_IWUSR, tc->dbgfs,
892 tc, &tool_link_fops);
893
894 debugfs_create_file("link_event", S_IWUSR, tc->dbgfs,
895 tc, &tool_link_event_fops);
896
806 for (i = 0; i < tc->mw_count; i++) { 897 for (i = 0; i < tc->mw_count; i++) {
807 char buf[30]; 898 char buf[30];
808 899
@@ -835,6 +926,7 @@ static int tool_probe(struct ntb_client *self, struct ntb_dev *ntb)
835 } 926 }
836 927
837 tc->ntb = ntb; 928 tc->ntb = ntb;
929 init_waitqueue_head(&tc->link_wq);
838 930
839 tc->mw_count = min(ntb_mw_count(tc->ntb), MAX_MWS); 931 tc->mw_count = min(ntb_mw_count(tc->ntb), MAX_MWS);
840 for (i = 0; i < tc->mw_count; i++) { 932 for (i = 0; i < tc->mw_count; i++) {