1#ifdef CONFIG_DEBUG_FS 2/* 3 * 4 * This file is provided under a dual BSD/GPLv2 license. When using or 5 * redistributing this file, you may do so under either license. 6 * 7 * GPL LICENSE SUMMARY 8 * 9 * Copyright(c) 2015 Intel Corporation. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of version 2 of the GNU General Public License as 13 * published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * BSD LICENSE 21 * 22 * Copyright(c) 2015 Intel Corporation. 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following conditions 26 * are met: 27 * 28 * - Redistributions of source code must retain the above copyright 29 * notice, this list of conditions and the following disclaimer. 30 * - Redistributions in binary form must reproduce the above copyright 31 * notice, this list of conditions and the following disclaimer in 32 * the documentation and/or other materials provided with the 33 * distribution. 34 * - Neither the name of Intel Corporation nor the names of its 35 * contributors may be used to endorse or promote products derived 36 * from this software without specific prior written permission. 37 * 38 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 39 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 40 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 41 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 42 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 44 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 45 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 46 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 47 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 48 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 49 * 50 */ 51#include <linux/debugfs.h> 52#include <linux/seq_file.h> 53#include <linux/kernel.h> 54#include <linux/export.h> 55 56#include "hfi.h" 57#include "debugfs.h" 58#include "device.h" 59#include "qp.h" 60#include "sdma.h" 61 62static struct dentry *hfi1_dbg_root; 63 64#define private2dd(file) (file_inode(file)->i_private) 65#define private2ppd(file) (file_inode(file)->i_private) 66 67#define DEBUGFS_SEQ_FILE_OPS(name) \ 68static const struct seq_operations _##name##_seq_ops = { \ 69 .start = _##name##_seq_start, \ 70 .next = _##name##_seq_next, \ 71 .stop = _##name##_seq_stop, \ 72 .show = _##name##_seq_show \ 73} 74#define DEBUGFS_SEQ_FILE_OPEN(name) \ 75static int _##name##_open(struct inode *inode, struct file *s) \ 76{ \ 77 struct seq_file *seq; \ 78 int ret; \ 79 ret = seq_open(s, &_##name##_seq_ops); \ 80 if (ret) \ 81 return ret; \ 82 seq = s->private_data; \ 83 seq->private = inode->i_private; \ 84 return 0; \ 85} 86 87#define DEBUGFS_FILE_OPS(name) \ 88static const struct file_operations _##name##_file_ops = { \ 89 .owner = THIS_MODULE, \ 90 .open = _##name##_open, \ 91 .read = seq_read, \ 92 .llseek = seq_lseek, \ 93 .release = seq_release \ 94} 95 96#define DEBUGFS_FILE_CREATE(name, parent, data, ops, mode) \ 97do { \ 98 struct dentry *ent; \ 99 ent = debugfs_create_file(name, mode, parent, \ 100 data, ops); \ 101 if (!ent) \ 102 pr_warn("create of %s failed\n", name); \ 103} while (0) 104 105 106#define DEBUGFS_SEQ_FILE_CREATE(name, parent, data) \ 107 DEBUGFS_FILE_CREATE(#name, parent, data, &_##name##_file_ops, S_IRUGO) 108 109static void *_opcode_stats_seq_start(struct seq_file *s, loff_t *pos) 110__acquires(RCU) 111{ 112 struct hfi1_opcode_stats_perctx *opstats; 113 114 rcu_read_lock(); 115 if (*pos >= ARRAY_SIZE(opstats->stats)) 116 return NULL; 117 return pos; 118} 119 120static void *_opcode_stats_seq_next(struct seq_file *s, void *v, loff_t *pos) 121{ 122 struct hfi1_opcode_stats_perctx *opstats; 123 124 ++*pos; 125 if (*pos >= ARRAY_SIZE(opstats->stats)) 126 return NULL; 127 return pos; 128} 129 130 131static void _opcode_stats_seq_stop(struct seq_file *s, void *v) 132__releases(RCU) 133{ 134 rcu_read_unlock(); 135} 136 137static int _opcode_stats_seq_show(struct seq_file *s, void *v) 138{ 139 loff_t *spos = v; 140 loff_t i = *spos, j; 141 u64 n_packets = 0, n_bytes = 0; 142 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private; 143 struct hfi1_devdata *dd = dd_from_dev(ibd); 144 145 for (j = 0; j < dd->first_user_ctxt; j++) { 146 if (!dd->rcd[j]) 147 continue; 148 n_packets += dd->rcd[j]->opstats->stats[i].n_packets; 149 n_bytes += dd->rcd[j]->opstats->stats[i].n_bytes; 150 } 151 if (!n_packets && !n_bytes) 152 return SEQ_SKIP; 153 seq_printf(s, "%02llx %llu/%llu\n", i, 154 (unsigned long long) n_packets, 155 (unsigned long long) n_bytes); 156 157 return 0; 158} 159 160DEBUGFS_SEQ_FILE_OPS(opcode_stats); 161DEBUGFS_SEQ_FILE_OPEN(opcode_stats) 162DEBUGFS_FILE_OPS(opcode_stats); 163 164static void *_ctx_stats_seq_start(struct seq_file *s, loff_t *pos) 165{ 166 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private; 167 struct hfi1_devdata *dd = dd_from_dev(ibd); 168 169 if (!*pos) 170 return SEQ_START_TOKEN; 171 if (*pos >= dd->first_user_ctxt) 172 return NULL; 173 return pos; 174} 175 176static void *_ctx_stats_seq_next(struct seq_file *s, void *v, loff_t *pos) 177{ 178 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private; 179 struct hfi1_devdata *dd = dd_from_dev(ibd); 180 181 if (v == SEQ_START_TOKEN) 182 return pos; 183 184 ++*pos; 185 if (*pos >= dd->first_user_ctxt) 186 return NULL; 187 return pos; 188} 189 190static void _ctx_stats_seq_stop(struct seq_file *s, void *v) 191{ 192 /* nothing allocated */ 193} 194 195static int _ctx_stats_seq_show(struct seq_file *s, void *v) 196{ 197 loff_t *spos; 198 loff_t i, j; 199 u64 n_packets = 0; 200 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private; 201 struct hfi1_devdata *dd = dd_from_dev(ibd); 202 203 if (v == SEQ_START_TOKEN) { 204 seq_puts(s, "Ctx:npkts\n"); 205 return 0; 206 } 207 208 spos = v; 209 i = *spos; 210 211 if (!dd->rcd[i]) 212 return SEQ_SKIP; 213 214 for (j = 0; j < ARRAY_SIZE(dd->rcd[i]->opstats->stats); j++) 215 n_packets += dd->rcd[i]->opstats->stats[j].n_packets; 216 217 if (!n_packets) 218 return SEQ_SKIP; 219 220 seq_printf(s, " %llu:%llu\n", i, n_packets); 221 return 0; 222} 223 224DEBUGFS_SEQ_FILE_OPS(ctx_stats); 225DEBUGFS_SEQ_FILE_OPEN(ctx_stats) 226DEBUGFS_FILE_OPS(ctx_stats); 227 228static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos) 229__acquires(RCU) 230{ 231 struct qp_iter *iter; 232 loff_t n = *pos; 233 234 rcu_read_lock(); 235 iter = qp_iter_init(s->private); 236 if (!iter) 237 return NULL; 238 239 while (n--) { 240 if (qp_iter_next(iter)) { 241 kfree(iter); 242 return NULL; 243 } 244 } 245 246 return iter; 247} 248 249static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr, 250 loff_t *pos) 251{ 252 struct qp_iter *iter = iter_ptr; 253 254 (*pos)++; 255 256 if (qp_iter_next(iter)) { 257 kfree(iter); 258 return NULL; 259 } 260 261 return iter; 262} 263 264static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr) 265__releases(RCU) 266{ 267 rcu_read_unlock(); 268} 269 270static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr) 271{ 272 struct qp_iter *iter = iter_ptr; 273 274 if (!iter) 275 return 0; 276 277 qp_iter_print(s, iter); 278 279 return 0; 280} 281 282DEBUGFS_SEQ_FILE_OPS(qp_stats); 283DEBUGFS_SEQ_FILE_OPEN(qp_stats) 284DEBUGFS_FILE_OPS(qp_stats); 285 286static void *_sdes_seq_start(struct seq_file *s, loff_t *pos) 287__acquires(RCU) 288{ 289 struct hfi1_ibdev *ibd; 290 struct hfi1_devdata *dd; 291 292 rcu_read_lock(); 293 ibd = (struct hfi1_ibdev *)s->private; 294 dd = dd_from_dev(ibd); 295 if (!dd->per_sdma || *pos >= dd->num_sdma) 296 return NULL; 297 return pos; 298} 299 300static void *_sdes_seq_next(struct seq_file *s, void *v, loff_t *pos) 301{ 302 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private; 303 struct hfi1_devdata *dd = dd_from_dev(ibd); 304 305 ++*pos; 306 if (!dd->per_sdma || *pos >= dd->num_sdma) 307 return NULL; 308 return pos; 309} 310 311 312static void _sdes_seq_stop(struct seq_file *s, void *v) 313__releases(RCU) 314{ 315 rcu_read_unlock(); 316} 317 318static int _sdes_seq_show(struct seq_file *s, void *v) 319{ 320 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private; 321 struct hfi1_devdata *dd = dd_from_dev(ibd); 322 loff_t *spos = v; 323 loff_t i = *spos; 324 325 sdma_seqfile_dump_sde(s, &dd->per_sdma[i]); 326 return 0; 327} 328 329DEBUGFS_SEQ_FILE_OPS(sdes); 330DEBUGFS_SEQ_FILE_OPEN(sdes) 331DEBUGFS_FILE_OPS(sdes); 332 333/* read the per-device counters */ 334static ssize_t dev_counters_read(struct file *file, char __user *buf, 335 size_t count, loff_t *ppos) 336{ 337 u64 *counters; 338 size_t avail; 339 struct hfi1_devdata *dd; 340 ssize_t rval; 341 342 rcu_read_lock(); 343 dd = private2dd(file); 344 avail = hfi1_read_cntrs(dd, *ppos, NULL, &counters); 345 rval = simple_read_from_buffer(buf, count, ppos, counters, avail); 346 rcu_read_unlock(); 347 return rval; 348} 349 350/* read the per-device counters */ 351static ssize_t dev_names_read(struct file *file, char __user *buf, 352 size_t count, loff_t *ppos) 353{ 354 char *names; 355 size_t avail; 356 struct hfi1_devdata *dd; 357 ssize_t rval; 358 359 rcu_read_lock(); 360 dd = private2dd(file); 361 avail = hfi1_read_cntrs(dd, *ppos, &names, NULL); 362 rval = simple_read_from_buffer(buf, count, ppos, names, avail); 363 rcu_read_unlock(); 364 return rval; 365} 366 367struct counter_info { 368 char *name; 369 const struct file_operations ops; 370}; 371 372/* 373 * Could use file_inode(file)->i_ino to figure out which file, 374 * instead of separate routine for each, but for now, this works... 375 */ 376 377/* read the per-port names (same for each port) */ 378static ssize_t portnames_read(struct file *file, char __user *buf, 379 size_t count, loff_t *ppos) 380{ 381 char *names; 382 size_t avail; 383 struct hfi1_devdata *dd; 384 ssize_t rval; 385 386 rcu_read_lock(); 387 dd = private2dd(file); 388 /* port number n/a here since names are constant */ 389 avail = hfi1_read_portcntrs(dd, *ppos, 0, &names, NULL); 390 rval = simple_read_from_buffer(buf, count, ppos, names, avail); 391 rcu_read_unlock(); 392 return rval; 393} 394 395/* read the per-port counters */ 396static ssize_t portcntrs_debugfs_read(struct file *file, char __user *buf, 397 size_t count, loff_t *ppos) 398{ 399 u64 *counters; 400 size_t avail; 401 struct hfi1_devdata *dd; 402 struct hfi1_pportdata *ppd; 403 ssize_t rval; 404 405 rcu_read_lock(); 406 ppd = private2ppd(file); 407 dd = ppd->dd; 408 avail = hfi1_read_portcntrs(dd, *ppos, ppd->port - 1, NULL, &counters); 409 rval = simple_read_from_buffer(buf, count, ppos, counters, avail); 410 rcu_read_unlock(); 411 return rval; 412} 413 414/* 415 * read the per-port QSFP data for ppd 416 */ 417static ssize_t qsfp_debugfs_dump(struct file *file, char __user *buf, 418 size_t count, loff_t *ppos) 419{ 420 struct hfi1_pportdata *ppd; 421 char *tmp; 422 int ret; 423 424 rcu_read_lock(); 425 ppd = private2ppd(file); 426 tmp = kmalloc(PAGE_SIZE, GFP_KERNEL); 427 if (!tmp) { 428 rcu_read_unlock(); 429 return -ENOMEM; 430 } 431 432 ret = qsfp_dump(ppd, tmp, PAGE_SIZE); 433 if (ret > 0) 434 ret = simple_read_from_buffer(buf, count, ppos, tmp, ret); 435 rcu_read_unlock(); 436 kfree(tmp); 437 return ret; 438} 439 440/* Do an i2c write operation on the chain for the given HFI. */ 441static ssize_t __i2c_debugfs_write(struct file *file, const char __user *buf, 442 size_t count, loff_t *ppos, u32 target) 443{ 444 struct hfi1_pportdata *ppd; 445 char *buff; 446 int ret; 447 int i2c_addr; 448 int offset; 449 int total_written; 450 451 rcu_read_lock(); 452 ppd = private2ppd(file); 453 454 buff = kmalloc(count, GFP_KERNEL); 455 if (!buff) { 456 ret = -ENOMEM; 457 goto _return; 458 } 459 460 ret = copy_from_user(buff, buf, count); 461 if (ret > 0) { 462 ret = -EFAULT; 463 goto _free; 464 } 465 466 i2c_addr = (*ppos >> 16) & 0xff; 467 offset = *ppos & 0xffff; 468 469 total_written = i2c_write(ppd, target, i2c_addr, offset, buff, count); 470 if (total_written < 0) { 471 ret = total_written; 472 goto _free; 473 } 474 475 *ppos += total_written; 476 477 ret = total_written; 478 479 _free: 480 kfree(buff); 481 _return: 482 rcu_read_unlock(); 483 return ret; 484} 485 486/* Do an i2c write operation on chain for HFI 0. */ 487static ssize_t i2c1_debugfs_write(struct file *file, const char __user *buf, 488 size_t count, loff_t *ppos) 489{ 490 return __i2c_debugfs_write(file, buf, count, ppos, 0); 491} 492 493/* Do an i2c write operation on chain for HFI 1. */ 494static ssize_t i2c2_debugfs_write(struct file *file, const char __user *buf, 495 size_t count, loff_t *ppos) 496{ 497 return __i2c_debugfs_write(file, buf, count, ppos, 1); 498} 499 500/* Do an i2c read operation on the chain for the given HFI. */ 501static ssize_t __i2c_debugfs_read(struct file *file, char __user *buf, 502 size_t count, loff_t *ppos, u32 target) 503{ 504 struct hfi1_pportdata *ppd; 505 char *buff; 506 int ret; 507 int i2c_addr; 508 int offset; 509 int total_read; 510 511 rcu_read_lock(); 512 ppd = private2ppd(file); 513 514 buff = kmalloc(count, GFP_KERNEL); 515 if (!buff) { 516 ret = -ENOMEM; 517 goto _return; 518 } 519 520 i2c_addr = (*ppos >> 16) & 0xff; 521 offset = *ppos & 0xffff; 522 523 total_read = i2c_read(ppd, target, i2c_addr, offset, buff, count); 524 if (total_read < 0) { 525 ret = total_read; 526 goto _free; 527 } 528 529 *ppos += total_read; 530 531 ret = copy_to_user(buf, buff, total_read); 532 if (ret > 0) { 533 ret = -EFAULT; 534 goto _free; 535 } 536 537 ret = total_read; 538 539 _free: 540 kfree(buff); 541 _return: 542 rcu_read_unlock(); 543 return ret; 544} 545 546/* Do an i2c read operation on chain for HFI 0. */ 547static ssize_t i2c1_debugfs_read(struct file *file, char __user *buf, 548 size_t count, loff_t *ppos) 549{ 550 return __i2c_debugfs_read(file, buf, count, ppos, 0); 551} 552 553/* Do an i2c read operation on chain for HFI 1. */ 554static ssize_t i2c2_debugfs_read(struct file *file, char __user *buf, 555 size_t count, loff_t *ppos) 556{ 557 return __i2c_debugfs_read(file, buf, count, ppos, 1); 558} 559 560/* Do a QSFP write operation on the i2c chain for the given HFI. */ 561static ssize_t __qsfp_debugfs_write(struct file *file, const char __user *buf, 562 size_t count, loff_t *ppos, u32 target) 563{ 564 struct hfi1_pportdata *ppd; 565 char *buff; 566 int ret; 567 int total_written; 568 569 rcu_read_lock(); 570 if (*ppos + count > QSFP_PAGESIZE * 4) { /* base page + page00-page03 */ 571 ret = -EINVAL; 572 goto _return; 573 } 574 575 ppd = private2ppd(file); 576 577 buff = kmalloc(count, GFP_KERNEL); 578 if (!buff) { 579 ret = -ENOMEM; 580 goto _return; 581 } 582 583 ret = copy_from_user(buff, buf, count); 584 if (ret > 0) { 585 ret = -EFAULT; 586 goto _free; 587 } 588 589 total_written = qsfp_write(ppd, target, *ppos, buff, count); 590 if (total_written < 0) { 591 ret = total_written; 592 goto _free; 593 } 594 595 *ppos += total_written; 596 597 ret = total_written; 598 599 _free: 600 kfree(buff); 601 _return: 602 rcu_read_unlock(); 603 return ret; 604} 605 606/* Do a QSFP write operation on i2c chain for HFI 0. */ 607static ssize_t qsfp1_debugfs_write(struct file *file, const char __user *buf, 608 size_t count, loff_t *ppos) 609{ 610 return __qsfp_debugfs_write(file, buf, count, ppos, 0); 611} 612 613/* Do a QSFP write operation on i2c chain for HFI 1. */ 614static ssize_t qsfp2_debugfs_write(struct file *file, const char __user *buf, 615 size_t count, loff_t *ppos) 616{ 617 return __qsfp_debugfs_write(file, buf, count, ppos, 1); 618} 619 620/* Do a QSFP read operation on the i2c chain for the given HFI. */ 621static ssize_t __qsfp_debugfs_read(struct file *file, char __user *buf, 622 size_t count, loff_t *ppos, u32 target) 623{ 624 struct hfi1_pportdata *ppd; 625 char *buff; 626 int ret; 627 int total_read; 628 629 rcu_read_lock(); 630 if (*ppos + count > QSFP_PAGESIZE * 4) { /* base page + page00-page03 */ 631 ret = -EINVAL; 632 goto _return; 633 } 634 635 ppd = private2ppd(file); 636 637 buff = kmalloc(count, GFP_KERNEL); 638 if (!buff) { 639 ret = -ENOMEM; 640 goto _return; 641 } 642 643 total_read = qsfp_read(ppd, target, *ppos, buff, count); 644 if (total_read < 0) { 645 ret = total_read; 646 goto _free; 647 } 648 649 *ppos += total_read; 650 651 ret = copy_to_user(buf, buff, total_read); 652 if (ret > 0) { 653 ret = -EFAULT; 654 goto _free; 655 } 656 657 ret = total_read; 658 659 _free: 660 kfree(buff); 661 _return: 662 rcu_read_unlock(); 663 return ret; 664} 665 666/* Do a QSFP read operation on i2c chain for HFI 0. */ 667static ssize_t qsfp1_debugfs_read(struct file *file, char __user *buf, 668 size_t count, loff_t *ppos) 669{ 670 return __qsfp_debugfs_read(file, buf, count, ppos, 0); 671} 672 673/* Do a QSFP read operation on i2c chain for HFI 1. */ 674static ssize_t qsfp2_debugfs_read(struct file *file, char __user *buf, 675 size_t count, loff_t *ppos) 676{ 677 return __qsfp_debugfs_read(file, buf, count, ppos, 1); 678} 679 680#define DEBUGFS_OPS(nm, readroutine, writeroutine) \ 681{ \ 682 .name = nm, \ 683 .ops = { \ 684 .read = readroutine, \ 685 .write = writeroutine, \ 686 .llseek = generic_file_llseek, \ 687 }, \ 688} 689 690static const struct counter_info cntr_ops[] = { 691 DEBUGFS_OPS("counter_names", dev_names_read, NULL), 692 DEBUGFS_OPS("counters", dev_counters_read, NULL), 693 DEBUGFS_OPS("portcounter_names", portnames_read, NULL), 694}; 695 696static const struct counter_info port_cntr_ops[] = { 697 DEBUGFS_OPS("port%dcounters", portcntrs_debugfs_read, NULL), 698 DEBUGFS_OPS("i2c1", i2c1_debugfs_read, i2c1_debugfs_write), 699 DEBUGFS_OPS("i2c2", i2c2_debugfs_read, i2c2_debugfs_write), 700 DEBUGFS_OPS("qsfp_dump%d", qsfp_debugfs_dump, NULL), 701 DEBUGFS_OPS("qsfp1", qsfp1_debugfs_read, qsfp1_debugfs_write), 702 DEBUGFS_OPS("qsfp2", qsfp2_debugfs_read, qsfp2_debugfs_write), 703}; 704 705void hfi1_dbg_ibdev_init(struct hfi1_ibdev *ibd) 706{ 707 char name[sizeof("port0counters") + 1]; 708 char link[10]; 709 struct hfi1_devdata *dd = dd_from_dev(ibd); 710 struct hfi1_pportdata *ppd; 711 int unit = dd->unit; 712 int i, j; 713 714 if (!hfi1_dbg_root) 715 return; 716 snprintf(name, sizeof(name), "%s_%d", class_name(), unit); 717 snprintf(link, sizeof(link), "%d", unit); 718 ibd->hfi1_ibdev_dbg = debugfs_create_dir(name, hfi1_dbg_root); 719 if (!ibd->hfi1_ibdev_dbg) { 720 pr_warn("create of %s failed\n", name); 721 return; 722 } 723 ibd->hfi1_ibdev_link = 724 debugfs_create_symlink(link, hfi1_dbg_root, name); 725 if (!ibd->hfi1_ibdev_link) { 726 pr_warn("create of %s symlink failed\n", name); 727 return; 728 } 729 DEBUGFS_SEQ_FILE_CREATE(opcode_stats, ibd->hfi1_ibdev_dbg, ibd); 730 DEBUGFS_SEQ_FILE_CREATE(ctx_stats, ibd->hfi1_ibdev_dbg, ibd); 731 DEBUGFS_SEQ_FILE_CREATE(qp_stats, ibd->hfi1_ibdev_dbg, ibd); 732 DEBUGFS_SEQ_FILE_CREATE(sdes, ibd->hfi1_ibdev_dbg, ibd); 733 /* dev counter files */ 734 for (i = 0; i < ARRAY_SIZE(cntr_ops); i++) 735 DEBUGFS_FILE_CREATE(cntr_ops[i].name, 736 ibd->hfi1_ibdev_dbg, 737 dd, 738 &cntr_ops[i].ops, S_IRUGO); 739 /* per port files */ 740 for (ppd = dd->pport, j = 0; j < dd->num_pports; j++, ppd++) 741 for (i = 0; i < ARRAY_SIZE(port_cntr_ops); i++) { 742 snprintf(name, 743 sizeof(name), 744 port_cntr_ops[i].name, 745 j + 1); 746 DEBUGFS_FILE_CREATE(name, 747 ibd->hfi1_ibdev_dbg, 748 ppd, 749 &port_cntr_ops[i].ops, 750 port_cntr_ops[i].ops.write == NULL ? 751 S_IRUGO : S_IRUGO|S_IWUSR); 752 } 753} 754 755void hfi1_dbg_ibdev_exit(struct hfi1_ibdev *ibd) 756{ 757 if (!hfi1_dbg_root) 758 goto out; 759 debugfs_remove(ibd->hfi1_ibdev_link); 760 debugfs_remove_recursive(ibd->hfi1_ibdev_dbg); 761out: 762 ibd->hfi1_ibdev_dbg = NULL; 763 synchronize_rcu(); 764} 765 766/* 767 * driver stats field names, one line per stat, single string. Used by 768 * programs like hfistats to print the stats in a way which works for 769 * different versions of drivers, without changing program source. 770 * if hfi1_ib_stats changes, this needs to change. Names need to be 771 * 12 chars or less (w/o newline), for proper display by hfistats utility. 772 */ 773static const char * const hfi1_statnames[] = { 774 /* must be element 0*/ 775 "KernIntr", 776 "ErrorIntr", 777 "Tx_Errs", 778 "Rcv_Errs", 779 "H/W_Errs", 780 "NoPIOBufs", 781 "CtxtsOpen", 782 "RcvLen_Errs", 783 "EgrBufFull", 784 "EgrHdrFull" 785}; 786 787static void *_driver_stats_names_seq_start(struct seq_file *s, loff_t *pos) 788__acquires(RCU) 789{ 790 rcu_read_lock(); 791 if (*pos >= ARRAY_SIZE(hfi1_statnames)) 792 return NULL; 793 return pos; 794} 795 796static void *_driver_stats_names_seq_next( 797 struct seq_file *s, 798 void *v, 799 loff_t *pos) 800{ 801 ++*pos; 802 if (*pos >= ARRAY_SIZE(hfi1_statnames)) 803 return NULL; 804 return pos; 805} 806 807static void _driver_stats_names_seq_stop(struct seq_file *s, void *v) 808__releases(RCU) 809{ 810 rcu_read_unlock(); 811} 812 813static int _driver_stats_names_seq_show(struct seq_file *s, void *v) 814{ 815 loff_t *spos = v; 816 817 seq_printf(s, "%s\n", hfi1_statnames[*spos]); 818 return 0; 819} 820 821DEBUGFS_SEQ_FILE_OPS(driver_stats_names); 822DEBUGFS_SEQ_FILE_OPEN(driver_stats_names) 823DEBUGFS_FILE_OPS(driver_stats_names); 824 825static void *_driver_stats_seq_start(struct seq_file *s, loff_t *pos) 826__acquires(RCU) 827{ 828 rcu_read_lock(); 829 if (*pos >= ARRAY_SIZE(hfi1_statnames)) 830 return NULL; 831 return pos; 832} 833 834static void *_driver_stats_seq_next(struct seq_file *s, void *v, loff_t *pos) 835{ 836 ++*pos; 837 if (*pos >= ARRAY_SIZE(hfi1_statnames)) 838 return NULL; 839 return pos; 840} 841 842static void _driver_stats_seq_stop(struct seq_file *s, void *v) 843__releases(RCU) 844{ 845 rcu_read_unlock(); 846} 847 848static u64 hfi1_sps_ints(void) 849{ 850 unsigned long flags; 851 struct hfi1_devdata *dd; 852 u64 sps_ints = 0; 853 854 spin_lock_irqsave(&hfi1_devs_lock, flags); 855 list_for_each_entry(dd, &hfi1_dev_list, list) { 856 sps_ints += get_all_cpu_total(dd->int_counter); 857 } 858 spin_unlock_irqrestore(&hfi1_devs_lock, flags); 859 return sps_ints; 860} 861 862static int _driver_stats_seq_show(struct seq_file *s, void *v) 863{ 864 loff_t *spos = v; 865 char *buffer; 866 u64 *stats = (u64 *)&hfi1_stats; 867 size_t sz = seq_get_buf(s, &buffer); 868 869 if (sz < sizeof(u64)) 870 return SEQ_SKIP; 871 /* special case for interrupts */ 872 if (*spos == 0) 873 *(u64 *)buffer = hfi1_sps_ints(); 874 else 875 *(u64 *)buffer = stats[*spos]; 876 seq_commit(s, sizeof(u64)); 877 return 0; 878} 879 880DEBUGFS_SEQ_FILE_OPS(driver_stats); 881DEBUGFS_SEQ_FILE_OPEN(driver_stats) 882DEBUGFS_FILE_OPS(driver_stats); 883 884void hfi1_dbg_init(void) 885{ 886 hfi1_dbg_root = debugfs_create_dir(DRIVER_NAME, NULL); 887 if (!hfi1_dbg_root) 888 pr_warn("init of debugfs failed\n"); 889 DEBUGFS_SEQ_FILE_CREATE(driver_stats_names, hfi1_dbg_root, NULL); 890 DEBUGFS_SEQ_FILE_CREATE(driver_stats, hfi1_dbg_root, NULL); 891} 892 893void hfi1_dbg_exit(void) 894{ 895 debugfs_remove_recursive(hfi1_dbg_root); 896 hfi1_dbg_root = NULL; 897} 898 899#endif 900