ipoib_fs.c 6.8 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
/*
 * Copyright (c) 2004 Topspin Communications.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

33
#include <linux/err.h>
L
Linus Torvalds 已提交
34
#include <linux/seq_file.h>
35
#include <linux/slab.h>
L
Linus Torvalds 已提交
36

37
struct file_operations;
L
Linus Torvalds 已提交
38

39
#include <linux/debugfs.h>
40
#include <linux/export.h>
41 42

#include "ipoib.h"
L
Linus Torvalds 已提交
43 44 45

static struct dentry *ipoib_root;

46 47 48 49 50 51 52 53 54 55 56 57
static void format_gid(union ib_gid *gid, char *buf)
{
	int i, n;

	for (n = 0, i = 0; i < 8; ++i) {
		n += sprintf(buf + n, "%x",
			     be16_to_cpu(((__be16 *) gid->raw)[i]));
		if (i < 7)
			buf[n++] = ':';
	}
}

L
Linus Torvalds 已提交
58 59 60 61 62 63 64 65 66 67 68
static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
{
	struct ipoib_mcast_iter *iter;
	loff_t n = *pos;

	iter = ipoib_mcast_iter_init(file->private);
	if (!iter)
		return NULL;

	while (n--) {
		if (ipoib_mcast_iter_next(iter)) {
69
			kfree(iter);
L
Linus Torvalds 已提交
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
			return NULL;
		}
	}

	return iter;
}

static void *ipoib_mcg_seq_next(struct seq_file *file, void *iter_ptr,
				   loff_t *pos)
{
	struct ipoib_mcast_iter *iter = iter_ptr;

	(*pos)++;

	if (ipoib_mcast_iter_next(iter)) {
85
		kfree(iter);
L
Linus Torvalds 已提交
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
		return NULL;
	}

	return iter;
}

static void ipoib_mcg_seq_stop(struct seq_file *file, void *iter_ptr)
{
	/* nothing for now */
}

static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr)
{
	struct ipoib_mcast_iter *iter = iter_ptr;
	char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
	union ib_gid mgid;
	unsigned long created;
	unsigned int queuelen, complete, send_only;

105 106
	if (!iter)
		return 0;
L
Linus Torvalds 已提交
107

108 109
	ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
			      &complete, &send_only);
L
Linus Torvalds 已提交
110

111
	format_gid(&mgid, gid_buf);
L
Linus Torvalds 已提交
112 113

	seq_printf(file,
114 115 116 117 118 119 120 121 122
		   "GID: %s\n"
		   "  created: %10ld\n"
		   "  queuelen: %9d\n"
		   "  complete: %9s\n"
		   "  send_only: %8s\n"
		   "\n",
		   gid_buf, created, queuelen,
		   complete ? "yes" : "no",
		   send_only ? "yes" : "no");
L
Linus Torvalds 已提交
123 124 125 126

	return 0;
}

127
static const struct seq_operations ipoib_mcg_seq_ops = {
L
Linus Torvalds 已提交
128 129 130 131 132 133 134 135 136 137 138
	.start = ipoib_mcg_seq_start,
	.next  = ipoib_mcg_seq_next,
	.stop  = ipoib_mcg_seq_stop,
	.show  = ipoib_mcg_seq_show,
};

static int ipoib_mcg_open(struct inode *inode, struct file *file)
{
	struct seq_file *seq;
	int ret;

139
	ret = seq_open(file, &ipoib_mcg_seq_ops);
L
Linus Torvalds 已提交
140 141 142 143
	if (ret)
		return ret;

	seq = file->private_data;
144
	seq->private = inode->i_private;
L
Linus Torvalds 已提交
145 146 147 148

	return 0;
}

149
static const struct file_operations ipoib_mcg_fops = {
L
Linus Torvalds 已提交
150 151 152 153 154 155 156
	.owner   = THIS_MODULE,
	.open    = ipoib_mcg_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = seq_release
};

157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
static void *ipoib_path_seq_start(struct seq_file *file, loff_t *pos)
{
	struct ipoib_path_iter *iter;
	loff_t n = *pos;

	iter = ipoib_path_iter_init(file->private);
	if (!iter)
		return NULL;

	while (n--) {
		if (ipoib_path_iter_next(iter)) {
			kfree(iter);
			return NULL;
		}
	}

	return iter;
}

static void *ipoib_path_seq_next(struct seq_file *file, void *iter_ptr,
				   loff_t *pos)
{
	struct ipoib_path_iter *iter = iter_ptr;

	(*pos)++;

	if (ipoib_path_iter_next(iter)) {
		kfree(iter);
		return NULL;
	}

	return iter;
}

static void ipoib_path_seq_stop(struct seq_file *file, void *iter_ptr)
{
	/* nothing for now */
}

static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)
{
	struct ipoib_path_iter *iter = iter_ptr;
	char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
	struct ipoib_path path;
	int rate;

	if (!iter)
		return 0;

	ipoib_path_iter_read(iter, &path);

	format_gid(&path.pathrec.dgid, gid_buf);

	seq_printf(file,
		   "GID: %s\n"
		   "  complete: %6s\n",
		   gid_buf, path.pathrec.dlid ? "yes" : "no");

	if (path.pathrec.dlid) {
216
		rate = ib_rate_to_mbps(path.pathrec.rate);
217 218 219 220

		seq_printf(file,
			   "  DLID:     0x%04x\n"
			   "  SL: %12d\n"
221
			   "  rate: %8d.%d Gb/sec\n",
222 223
			   be16_to_cpu(path.pathrec.dlid),
			   path.pathrec.sl,
224
			   rate / 1000, rate % 1000);
225 226 227 228 229 230 231
	}

	seq_putc(file, '\n');

	return 0;
}

232
static const struct seq_operations ipoib_path_seq_ops = {
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
	.start = ipoib_path_seq_start,
	.next  = ipoib_path_seq_next,
	.stop  = ipoib_path_seq_stop,
	.show  = ipoib_path_seq_show,
};

static int ipoib_path_open(struct inode *inode, struct file *file)
{
	struct seq_file *seq;
	int ret;

	ret = seq_open(file, &ipoib_path_seq_ops);
	if (ret)
		return ret;

	seq = file->private_data;
249
	seq->private = inode->i_private;
250 251 252 253

	return 0;
}

254
static const struct file_operations ipoib_path_fops = {
255 256 257 258 259 260 261 262
	.owner   = THIS_MODULE,
	.open    = ipoib_path_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = seq_release
};

void ipoib_create_debug_files(struct net_device *dev)
L
Linus Torvalds 已提交
263 264
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
265
	char name[IFNAMSIZ + sizeof "_path"];
L
Linus Torvalds 已提交
266 267

	snprintf(name, sizeof name, "%s_mcg", dev->name);
268
	priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
269 270 271 272 273 274 275 276 277
					       ipoib_root, dev, &ipoib_mcg_fops);
	if (!priv->mcg_dentry)
		ipoib_warn(priv, "failed to create mcg debug file\n");

	snprintf(name, sizeof name, "%s_path", dev->name);
	priv->path_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
						ipoib_root, dev, &ipoib_path_fops);
	if (!priv->path_dentry)
		ipoib_warn(priv, "failed to create path debug file\n");
L
Linus Torvalds 已提交
278 279
}

280
void ipoib_delete_debug_files(struct net_device *dev)
L
Linus Torvalds 已提交
281 282 283
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);

284 285
	WARN_ONCE(!priv->mcg_dentry, "null mcg debug file\n");
	WARN_ONCE(!priv->path_dentry, "null path debug file\n");
286 287
	debugfs_remove(priv->mcg_dentry);
	debugfs_remove(priv->path_dentry);
288
	priv->mcg_dentry = priv->path_dentry = NULL;
L
Linus Torvalds 已提交
289 290 291 292
}

int ipoib_register_debugfs(void)
{
293 294
	ipoib_root = debugfs_create_dir("ipoib", NULL);
	return ipoib_root ? 0 : -ENOMEM;
L
Linus Torvalds 已提交
295 296 297 298
}

void ipoib_unregister_debugfs(void)
{
299
	debugfs_remove(ipoib_root);
L
Linus Torvalds 已提交
300
}