11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2004 Topspin Communications.  All rights reserved.
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software is available to you under a choice of one of two
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * licenses.  You may choose to be licensed under the terms of the GNU
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * General Public License (GPL) Version 2, available from the file
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * COPYING in the main directory of this source tree, or the
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OpenIB.org BSD license below:
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Redistribution and use in source and binary forms, with or
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     without modification, are permitted provided that the following
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     conditions are met:
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      - Redistributions of source code must retain the above
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        copyright notice, this list of conditions and the following
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        disclaimer.
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      - Redistributions in binary form must reproduce the above
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        copyright notice, this list of conditions and the following
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        disclaimer in the documentation and/or other materials
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        provided with the distribution.
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SOFTWARE.
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
339adec1a808603698bd7ff47f3883bd7cd1383f90Roland Dreier#include <linux/err.h>
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/seq_file.h>
355a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
379adec1a808603698bd7ff47f3883bd7cd1383f90Roland Dreierstruct file_operations;
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
399adec1a808603698bd7ff47f3883bd7cd1383f90Roland Dreier#include <linux/debugfs.h>
40b108d9764cff25262bf764542ed1998d3e568962Paul Gortmaker#include <linux/export.h>
419adec1a808603698bd7ff47f3883bd7cd1383f90Roland Dreier
429adec1a808603698bd7ff47f3883bd7cd1383f90Roland Dreier#include "ipoib.h"
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dentry *ipoib_root;
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
461732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreierstatic void format_gid(union ib_gid *gid, char *buf)
471732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier{
481732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	int i, n;
491732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
501732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	for (n = 0, i = 0; i < 8; ++i) {
511732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		n += sprintf(buf + n, "%x",
521732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier			     be16_to_cpu(((__be16 *) gid->raw)[i]));
531732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		if (i < 7)
541732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier			buf[n++] = ':';
551732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	}
561732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier}
571732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ipoib_mcast_iter *iter;
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	loff_t n = *pos;
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	iter = ipoib_mcast_iter_init(file->private);
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!iter)
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (n--) {
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ipoib_mcast_iter_next(iter)) {
691732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier			kfree(iter);
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return NULL;
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return iter;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void *ipoib_mcg_seq_next(struct seq_file *file, void *iter_ptr,
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   loff_t *pos)
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ipoib_mcast_iter *iter = iter_ptr;
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	(*pos)++;
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ipoib_mcast_iter_next(iter)) {
851732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		kfree(iter);
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return iter;
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ipoib_mcg_seq_stop(struct seq_file *file, void *iter_ptr)
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* nothing for now */
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr)
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ipoib_mcast_iter *iter = iter_ptr;
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union ib_gid mgid;
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long created;
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int queuelen, complete, send_only;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1051732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	if (!iter)
1061732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		return 0;
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1081732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
1091732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier			      &complete, &send_only);
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1111732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	format_gid(&mgid, gid_buf);
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	seq_printf(file,
1141732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   "GID: %s\n"
1151732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   "  created: %10ld\n"
1161732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   "  queuelen: %9d\n"
1171732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   "  complete: %9s\n"
1181732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   "  send_only: %8s\n"
1191732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   "\n",
1201732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   gid_buf, created, queuelen,
1211732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   complete ? "yes" : "no",
1221732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   send_only ? "yes" : "no");
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1271cf18d5aab5144866cb5221250905623b03a32a9Jan Engelhardtstatic const struct seq_operations ipoib_mcg_seq_ops = {
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.start = ipoib_mcg_seq_start,
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.next  = ipoib_mcg_seq_next,
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.stop  = ipoib_mcg_seq_stop,
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.show  = ipoib_mcg_seq_show,
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ipoib_mcg_open(struct inode *inode, struct file *file)
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct seq_file *seq;
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1391732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	ret = seq_open(file, &ipoib_mcg_seq_ops);
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ret)
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ret;
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	seq = file->private_data;
1448e18e2941c53416aa219708e7dcad21fb4bd6794Theodore Ts'o	seq->private = inode->i_private;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1492b8693c0617e972fc0b2fd1ebf8de97e15b656c3Arjan van de Venstatic const struct file_operations ipoib_mcg_fops = {
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.owner   = THIS_MODULE,
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.open    = ipoib_mcg_open,
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.read    = seq_read,
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.llseek  = seq_lseek,
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.release = seq_release
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1571732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreierstatic void *ipoib_path_seq_start(struct seq_file *file, loff_t *pos)
1581732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier{
1591732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	struct ipoib_path_iter *iter;
1601732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	loff_t n = *pos;
1611732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
1621732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	iter = ipoib_path_iter_init(file->private);
1631732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	if (!iter)
1641732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		return NULL;
1651732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
1661732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	while (n--) {
1671732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		if (ipoib_path_iter_next(iter)) {
1681732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier			kfree(iter);
1691732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier			return NULL;
1701732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		}
1711732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	}
1721732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
1731732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	return iter;
1741732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier}
1751732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
1761732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreierstatic void *ipoib_path_seq_next(struct seq_file *file, void *iter_ptr,
1771732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier				   loff_t *pos)
1781732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier{
1791732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	struct ipoib_path_iter *iter = iter_ptr;
1801732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
1811732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	(*pos)++;
1821732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
1831732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	if (ipoib_path_iter_next(iter)) {
1841732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		kfree(iter);
1851732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		return NULL;
1861732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	}
1871732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
1881732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	return iter;
1891732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier}
1901732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
1911732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreierstatic void ipoib_path_seq_stop(struct seq_file *file, void *iter_ptr)
1921732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier{
1931732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	/* nothing for now */
1941732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier}
1951732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
1961732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreierstatic int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)
1971732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier{
1981732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	struct ipoib_path_iter *iter = iter_ptr;
1991732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
2001732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	struct ipoib_path path;
2011732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	int rate;
2021732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2031732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	if (!iter)
2041732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		return 0;
2051732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2061732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	ipoib_path_iter_read(iter, &path);
2071732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2081732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	format_gid(&path.pathrec.dgid, gid_buf);
2091732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2101732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	seq_printf(file,
2111732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   "GID: %s\n"
2121732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   "  complete: %6s\n",
2131732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		   gid_buf, path.pathrec.dlid ? "yes" : "no");
2141732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2151732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	if (path.pathrec.dlid) {
216e36fb88a9a0fb8ac4b87c8ac709214a408de6d97Marcel Apfelbaum		rate = ib_rate_to_mbps(path.pathrec.rate);
2171732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2181732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		seq_printf(file,
2191732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier			   "  DLID:     0x%04x\n"
2201732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier			   "  SL: %12d\n"
221e36fb88a9a0fb8ac4b87c8ac709214a408de6d97Marcel Apfelbaum			   "  rate: %8d.%d Gb/sec\n",
2221732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier			   be16_to_cpu(path.pathrec.dlid),
2231732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier			   path.pathrec.sl,
224e36fb88a9a0fb8ac4b87c8ac709214a408de6d97Marcel Apfelbaum			   rate / 1000, rate % 1000);
2251732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	}
2261732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2271732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	seq_putc(file, '\n');
2281732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2291732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	return 0;
2301732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier}
2311732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2321cf18d5aab5144866cb5221250905623b03a32a9Jan Engelhardtstatic const struct seq_operations ipoib_path_seq_ops = {
2331732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	.start = ipoib_path_seq_start,
2341732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	.next  = ipoib_path_seq_next,
2351732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	.stop  = ipoib_path_seq_stop,
2361732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	.show  = ipoib_path_seq_show,
2371732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier};
2381732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2391732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreierstatic int ipoib_path_open(struct inode *inode, struct file *file)
2401732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier{
2411732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	struct seq_file *seq;
2421732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	int ret;
2431732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2441732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	ret = seq_open(file, &ipoib_path_seq_ops);
2451732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	if (ret)
2461732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		return ret;
2471732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2481732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	seq = file->private_data;
2498e18e2941c53416aa219708e7dcad21fb4bd6794Theodore Ts'o	seq->private = inode->i_private;
2501732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2511732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	return 0;
2521732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier}
2531732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2542b8693c0617e972fc0b2fd1ebf8de97e15b656c3Arjan van de Venstatic const struct file_operations ipoib_path_fops = {
2551732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	.owner   = THIS_MODULE,
2561732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	.open    = ipoib_path_open,
2571732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	.read    = seq_read,
2581732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	.llseek  = seq_lseek,
2591732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	.release = seq_release
2601732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier};
2611732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2621732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreiervoid ipoib_create_debug_files(struct net_device *dev)
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ipoib_dev_priv *priv = netdev_priv(dev);
2651732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	char name[IFNAMSIZ + sizeof "_path"];
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	snprintf(name, sizeof name, "%s_mcg", dev->name);
2689adec1a808603698bd7ff47f3883bd7cd1383f90Roland Dreier	priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
2691732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier					       ipoib_root, dev, &ipoib_mcg_fops);
2701732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	if (!priv->mcg_dentry)
2711732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		ipoib_warn(priv, "failed to create mcg debug file\n");
2721732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier
2731732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	snprintf(name, sizeof name, "%s_path", dev->name);
2741732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	priv->path_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
2751732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier						ipoib_root, dev, &ipoib_path_fops);
2761732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	if (!priv->path_dentry)
2771732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		ipoib_warn(priv, "failed to create path debug file\n");
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2801732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreiervoid ipoib_delete_debug_files(struct net_device *dev)
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ipoib_dev_priv *priv = netdev_priv(dev);
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2849adec1a808603698bd7ff47f3883bd7cd1383f90Roland Dreier	if (priv->mcg_dentry)
2859adec1a808603698bd7ff47f3883bd7cd1383f90Roland Dreier		debugfs_remove(priv->mcg_dentry);
2861732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier	if (priv->path_dentry)
2871732b0ef3b3a02e3df328086fb3018741c5476daRoland Dreier		debugfs_remove(priv->path_dentry);
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ipoib_register_debugfs(void)
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2929adec1a808603698bd7ff47f3883bd7cd1383f90Roland Dreier	ipoib_root = debugfs_create_dir("ipoib", NULL);
2939adec1a808603698bd7ff47f3883bd7cd1383f90Roland Dreier	return ipoib_root ? 0 : -ENOMEM;
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid ipoib_unregister_debugfs(void)
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2989adec1a808603698bd7ff47f3883bd7cd1383f90Roland Dreier	debugfs_remove(ipoib_root);
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
300