1/* 2 * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. 3 * Copyright (c) 2006 PathScale, Inc. All rights reserved. 4 * 5 * This software is available to you under a choice of one of two 6 * licenses. You may choose to be licensed under the terms of the GNU 7 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the 9 * OpenIB.org BSD license below: 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the following 13 * conditions are met: 14 * 15 * - Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials 22 * provided with the distribution. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * SOFTWARE. 32 */ 33 34#include <linux/module.h> 35#include <linux/fs.h> 36#include <linux/mount.h> 37#include <linux/pagemap.h> 38#include <linux/init.h> 39#include <linux/namei.h> 40 41#include "qib.h" 42 43#define QIBFS_MAGIC 0x726a77 44 45static struct super_block *qib_super; 46 47#define private2dd(file) ((file)->f_dentry->d_inode->i_private) 48 49static int qibfs_mknod(struct inode *dir, struct dentry *dentry, 50 int mode, const struct file_operations *fops, 51 void *data) 52{ 53 int error; 54 struct inode *inode = new_inode(dir->i_sb); 55 56 if (!inode) { 57 error = -EPERM; 58 goto bail; 59 } 60 61 inode->i_mode = mode; 62 inode->i_uid = 0; 63 inode->i_gid = 0; 64 inode->i_blocks = 0; 65 inode->i_atime = CURRENT_TIME; 66 inode->i_mtime = inode->i_atime; 67 inode->i_ctime = inode->i_atime; 68 inode->i_private = data; 69 if ((mode & S_IFMT) == S_IFDIR) { 70 inode->i_op = &simple_dir_inode_operations; 71 inc_nlink(inode); 72 inc_nlink(dir); 73 } 74 75 inode->i_fop = fops; 76 77 d_instantiate(dentry, inode); 78 error = 0; 79 80bail: 81 return error; 82} 83 84static int create_file(const char *name, mode_t mode, 85 struct dentry *parent, struct dentry **dentry, 86 const struct file_operations *fops, void *data) 87{ 88 int error; 89 90 *dentry = NULL; 91 mutex_lock(&parent->d_inode->i_mutex); 92 *dentry = lookup_one_len(name, parent, strlen(name)); 93 if (!IS_ERR(*dentry)) 94 error = qibfs_mknod(parent->d_inode, *dentry, 95 mode, fops, data); 96 else 97 error = PTR_ERR(*dentry); 98 mutex_unlock(&parent->d_inode->i_mutex); 99 100 return error; 101} 102 103static ssize_t driver_stats_read(struct file *file, char __user *buf, 104 size_t count, loff_t *ppos) 105{ 106 return simple_read_from_buffer(buf, count, ppos, &qib_stats, 107 sizeof qib_stats); 108} 109 110/* 111 * driver stats field names, one line per stat, single string. Used by 112 * programs like ipathstats to print the stats in a way which works for 113 * different versions of drivers, without changing program source. 114 * if qlogic_ib_stats changes, this needs to change. Names need to be 115 * 12 chars or less (w/o newline), for proper display by ipathstats utility. 116 */ 117static const char qib_statnames[] = 118 "KernIntr\n" 119 "ErrorIntr\n" 120 "Tx_Errs\n" 121 "Rcv_Errs\n" 122 "H/W_Errs\n" 123 "NoPIOBufs\n" 124 "CtxtsOpen\n" 125 "RcvLen_Errs\n" 126 "EgrBufFull\n" 127 "EgrHdrFull\n" 128 ; 129 130static ssize_t driver_names_read(struct file *file, char __user *buf, 131 size_t count, loff_t *ppos) 132{ 133 return simple_read_from_buffer(buf, count, ppos, qib_statnames, 134 sizeof qib_statnames - 1); /* no null */ 135} 136 137static const struct file_operations driver_ops[] = { 138 { .read = driver_stats_read, .llseek = generic_file_llseek, }, 139 { .read = driver_names_read, .llseek = generic_file_llseek, }, 140}; 141 142/* read the per-device counters */ 143static ssize_t dev_counters_read(struct file *file, char __user *buf, 144 size_t count, loff_t *ppos) 145{ 146 u64 *counters; 147 size_t avail; 148 struct qib_devdata *dd = private2dd(file); 149 150 avail = dd->f_read_cntrs(dd, *ppos, NULL, &counters); 151 return simple_read_from_buffer(buf, count, ppos, counters, avail); 152} 153 154/* read the per-device counters */ 155static ssize_t dev_names_read(struct file *file, char __user *buf, 156 size_t count, loff_t *ppos) 157{ 158 char *names; 159 size_t avail; 160 struct qib_devdata *dd = private2dd(file); 161 162 avail = dd->f_read_cntrs(dd, *ppos, &names, NULL); 163 return simple_read_from_buffer(buf, count, ppos, names, avail); 164} 165 166static const struct file_operations cntr_ops[] = { 167 { .read = dev_counters_read, .llseek = generic_file_llseek, }, 168 { .read = dev_names_read, .llseek = generic_file_llseek, }, 169}; 170 171/* 172 * Could use file->f_dentry->d_inode->i_ino to figure out which file, 173 * instead of separate routine for each, but for now, this works... 174 */ 175 176/* read the per-port names (same for each port) */ 177static ssize_t portnames_read(struct file *file, char __user *buf, 178 size_t count, loff_t *ppos) 179{ 180 char *names; 181 size_t avail; 182 struct qib_devdata *dd = private2dd(file); 183 184 avail = dd->f_read_portcntrs(dd, *ppos, 0, &names, NULL); 185 return simple_read_from_buffer(buf, count, ppos, names, avail); 186} 187 188/* read the per-port counters for port 1 (pidx 0) */ 189static ssize_t portcntrs_1_read(struct file *file, char __user *buf, 190 size_t count, loff_t *ppos) 191{ 192 u64 *counters; 193 size_t avail; 194 struct qib_devdata *dd = private2dd(file); 195 196 avail = dd->f_read_portcntrs(dd, *ppos, 0, NULL, &counters); 197 return simple_read_from_buffer(buf, count, ppos, counters, avail); 198} 199 200/* read the per-port counters for port 2 (pidx 1) */ 201static ssize_t portcntrs_2_read(struct file *file, char __user *buf, 202 size_t count, loff_t *ppos) 203{ 204 u64 *counters; 205 size_t avail; 206 struct qib_devdata *dd = private2dd(file); 207 208 avail = dd->f_read_portcntrs(dd, *ppos, 1, NULL, &counters); 209 return simple_read_from_buffer(buf, count, ppos, counters, avail); 210} 211 212static const struct file_operations portcntr_ops[] = { 213 { .read = portnames_read, .llseek = generic_file_llseek, }, 214 { .read = portcntrs_1_read, .llseek = generic_file_llseek, }, 215 { .read = portcntrs_2_read, .llseek = generic_file_llseek, }, 216}; 217 218/* 219 * read the per-port QSFP data for port 1 (pidx 0) 220 */ 221static ssize_t qsfp_1_read(struct file *file, char __user *buf, 222 size_t count, loff_t *ppos) 223{ 224 struct qib_devdata *dd = private2dd(file); 225 char *tmp; 226 int ret; 227 228 tmp = kmalloc(PAGE_SIZE, GFP_KERNEL); 229 if (!tmp) 230 return -ENOMEM; 231 232 ret = qib_qsfp_dump(dd->pport, tmp, PAGE_SIZE); 233 if (ret > 0) 234 ret = simple_read_from_buffer(buf, count, ppos, tmp, ret); 235 kfree(tmp); 236 return ret; 237} 238 239/* 240 * read the per-port QSFP data for port 2 (pidx 1) 241 */ 242static ssize_t qsfp_2_read(struct file *file, char __user *buf, 243 size_t count, loff_t *ppos) 244{ 245 struct qib_devdata *dd = private2dd(file); 246 char *tmp; 247 int ret; 248 249 if (dd->num_pports < 2) 250 return -ENODEV; 251 252 tmp = kmalloc(PAGE_SIZE, GFP_KERNEL); 253 if (!tmp) 254 return -ENOMEM; 255 256 ret = qib_qsfp_dump(dd->pport + 1, tmp, PAGE_SIZE); 257 if (ret > 0) 258 ret = simple_read_from_buffer(buf, count, ppos, tmp, ret); 259 kfree(tmp); 260 return ret; 261} 262 263static const struct file_operations qsfp_ops[] = { 264 { .read = qsfp_1_read, .llseek = generic_file_llseek, }, 265 { .read = qsfp_2_read, .llseek = generic_file_llseek, }, 266}; 267 268static ssize_t flash_read(struct file *file, char __user *buf, 269 size_t count, loff_t *ppos) 270{ 271 struct qib_devdata *dd; 272 ssize_t ret; 273 loff_t pos; 274 char *tmp; 275 276 pos = *ppos; 277 278 if (pos < 0) { 279 ret = -EINVAL; 280 goto bail; 281 } 282 283 if (pos >= sizeof(struct qib_flash)) { 284 ret = 0; 285 goto bail; 286 } 287 288 if (count > sizeof(struct qib_flash) - pos) 289 count = sizeof(struct qib_flash) - pos; 290 291 tmp = kmalloc(count, GFP_KERNEL); 292 if (!tmp) { 293 ret = -ENOMEM; 294 goto bail; 295 } 296 297 dd = private2dd(file); 298 if (qib_eeprom_read(dd, pos, tmp, count)) { 299 qib_dev_err(dd, "failed to read from flash\n"); 300 ret = -ENXIO; 301 goto bail_tmp; 302 } 303 304 if (copy_to_user(buf, tmp, count)) { 305 ret = -EFAULT; 306 goto bail_tmp; 307 } 308 309 *ppos = pos + count; 310 ret = count; 311 312bail_tmp: 313 kfree(tmp); 314 315bail: 316 return ret; 317} 318 319static ssize_t flash_write(struct file *file, const char __user *buf, 320 size_t count, loff_t *ppos) 321{ 322 struct qib_devdata *dd; 323 ssize_t ret; 324 loff_t pos; 325 char *tmp; 326 327 pos = *ppos; 328 329 if (pos != 0) { 330 ret = -EINVAL; 331 goto bail; 332 } 333 334 if (count != sizeof(struct qib_flash)) { 335 ret = -EINVAL; 336 goto bail; 337 } 338 339 tmp = kmalloc(count, GFP_KERNEL); 340 if (!tmp) { 341 ret = -ENOMEM; 342 goto bail; 343 } 344 345 if (copy_from_user(tmp, buf, count)) { 346 ret = -EFAULT; 347 goto bail_tmp; 348 } 349 350 dd = private2dd(file); 351 if (qib_eeprom_write(dd, pos, tmp, count)) { 352 ret = -ENXIO; 353 qib_dev_err(dd, "failed to write to flash\n"); 354 goto bail_tmp; 355 } 356 357 *ppos = pos + count; 358 ret = count; 359 360bail_tmp: 361 kfree(tmp); 362 363bail: 364 return ret; 365} 366 367static const struct file_operations flash_ops = { 368 .read = flash_read, 369 .write = flash_write, 370}; 371 372static int add_cntr_files(struct super_block *sb, struct qib_devdata *dd) 373{ 374 struct dentry *dir, *tmp; 375 char unit[10]; 376 int ret, i; 377 378 /* create the per-unit directory */ 379 snprintf(unit, sizeof unit, "%u", dd->unit); 380 ret = create_file(unit, S_IFDIR|S_IRUGO|S_IXUGO, sb->s_root, &dir, 381 &simple_dir_operations, dd); 382 if (ret) { 383 printk(KERN_ERR "create_file(%s) failed: %d\n", unit, ret); 384 goto bail; 385 } 386 387 /* create the files in the new directory */ 388 ret = create_file("counters", S_IFREG|S_IRUGO, dir, &tmp, 389 &cntr_ops[0], dd); 390 if (ret) { 391 printk(KERN_ERR "create_file(%s/counters) failed: %d\n", 392 unit, ret); 393 goto bail; 394 } 395 ret = create_file("counter_names", S_IFREG|S_IRUGO, dir, &tmp, 396 &cntr_ops[1], dd); 397 if (ret) { 398 printk(KERN_ERR "create_file(%s/counter_names) failed: %d\n", 399 unit, ret); 400 goto bail; 401 } 402 ret = create_file("portcounter_names", S_IFREG|S_IRUGO, dir, &tmp, 403 &portcntr_ops[0], dd); 404 if (ret) { 405 printk(KERN_ERR "create_file(%s/%s) failed: %d\n", 406 unit, "portcounter_names", ret); 407 goto bail; 408 } 409 for (i = 1; i <= dd->num_pports; i++) { 410 char fname[24]; 411 412 sprintf(fname, "port%dcounters", i); 413 /* create the files in the new directory */ 414 ret = create_file(fname, S_IFREG|S_IRUGO, dir, &tmp, 415 &portcntr_ops[i], dd); 416 if (ret) { 417 printk(KERN_ERR "create_file(%s/%s) failed: %d\n", 418 unit, fname, ret); 419 goto bail; 420 } 421 if (!(dd->flags & QIB_HAS_QSFP)) 422 continue; 423 sprintf(fname, "qsfp%d", i); 424 ret = create_file(fname, S_IFREG|S_IRUGO, dir, &tmp, 425 &qsfp_ops[i - 1], dd); 426 if (ret) { 427 printk(KERN_ERR "create_file(%s/%s) failed: %d\n", 428 unit, fname, ret); 429 goto bail; 430 } 431 } 432 433 ret = create_file("flash", S_IFREG|S_IWUSR|S_IRUGO, dir, &tmp, 434 &flash_ops, dd); 435 if (ret) 436 printk(KERN_ERR "create_file(%s/flash) failed: %d\n", 437 unit, ret); 438bail: 439 return ret; 440} 441 442static int remove_file(struct dentry *parent, char *name) 443{ 444 struct dentry *tmp; 445 int ret; 446 447 tmp = lookup_one_len(name, parent, strlen(name)); 448 449 if (IS_ERR(tmp)) { 450 ret = PTR_ERR(tmp); 451 goto bail; 452 } 453 454 spin_lock(&dcache_lock); 455 spin_lock(&tmp->d_lock); 456 if (!(d_unhashed(tmp) && tmp->d_inode)) { 457 dget_locked(tmp); 458 __d_drop(tmp); 459 spin_unlock(&tmp->d_lock); 460 spin_unlock(&dcache_lock); 461 simple_unlink(parent->d_inode, tmp); 462 } else { 463 spin_unlock(&tmp->d_lock); 464 spin_unlock(&dcache_lock); 465 } 466 467 ret = 0; 468bail: 469 /* 470 * We don't expect clients to care about the return value, but 471 * it's there if they need it. 472 */ 473 return ret; 474} 475 476static int remove_device_files(struct super_block *sb, 477 struct qib_devdata *dd) 478{ 479 struct dentry *dir, *root; 480 char unit[10]; 481 int ret, i; 482 483 root = dget(sb->s_root); 484 mutex_lock(&root->d_inode->i_mutex); 485 snprintf(unit, sizeof unit, "%u", dd->unit); 486 dir = lookup_one_len(unit, root, strlen(unit)); 487 488 if (IS_ERR(dir)) { 489 ret = PTR_ERR(dir); 490 printk(KERN_ERR "Lookup of %s failed\n", unit); 491 goto bail; 492 } 493 494 remove_file(dir, "counters"); 495 remove_file(dir, "counter_names"); 496 remove_file(dir, "portcounter_names"); 497 for (i = 0; i < dd->num_pports; i++) { 498 char fname[24]; 499 500 sprintf(fname, "port%dcounters", i + 1); 501 remove_file(dir, fname); 502 if (dd->flags & QIB_HAS_QSFP) { 503 sprintf(fname, "qsfp%d", i + 1); 504 remove_file(dir, fname); 505 } 506 } 507 remove_file(dir, "flash"); 508 d_delete(dir); 509 ret = simple_rmdir(root->d_inode, dir); 510 511bail: 512 mutex_unlock(&root->d_inode->i_mutex); 513 dput(root); 514 return ret; 515} 516 517/* 518 * This fills everything in when the fs is mounted, to handle umount/mount 519 * after device init. The direct add_cntr_files() call handles adding 520 * them from the init code, when the fs is already mounted. 521 */ 522static int qibfs_fill_super(struct super_block *sb, void *data, int silent) 523{ 524 struct qib_devdata *dd, *tmp; 525 unsigned long flags; 526 int ret; 527 528 static struct tree_descr files[] = { 529 [2] = {"driver_stats", &driver_ops[0], S_IRUGO}, 530 [3] = {"driver_stats_names", &driver_ops[1], S_IRUGO}, 531 {""}, 532 }; 533 534 ret = simple_fill_super(sb, QIBFS_MAGIC, files); 535 if (ret) { 536 printk(KERN_ERR "simple_fill_super failed: %d\n", ret); 537 goto bail; 538 } 539 540 spin_lock_irqsave(&qib_devs_lock, flags); 541 542 list_for_each_entry_safe(dd, tmp, &qib_dev_list, list) { 543 spin_unlock_irqrestore(&qib_devs_lock, flags); 544 ret = add_cntr_files(sb, dd); 545 if (ret) 546 goto bail; 547 spin_lock_irqsave(&qib_devs_lock, flags); 548 } 549 550 spin_unlock_irqrestore(&qib_devs_lock, flags); 551 552bail: 553 return ret; 554} 555 556static int qibfs_get_sb(struct file_system_type *fs_type, int flags, 557 const char *dev_name, void *data, struct vfsmount *mnt) 558{ 559 int ret = get_sb_single(fs_type, flags, data, 560 qibfs_fill_super, mnt); 561 if (ret >= 0) 562 qib_super = mnt->mnt_sb; 563 return ret; 564} 565 566static void qibfs_kill_super(struct super_block *s) 567{ 568 kill_litter_super(s); 569 qib_super = NULL; 570} 571 572int qibfs_add(struct qib_devdata *dd) 573{ 574 int ret; 575 576 /* 577 * On first unit initialized, qib_super will not yet exist 578 * because nobody has yet tried to mount the filesystem, so 579 * we can't consider that to be an error; if an error occurs 580 * during the mount, that will get a complaint, so this is OK. 581 * add_cntr_files() for all units is done at mount from 582 * qibfs_fill_super(), so one way or another, everything works. 583 */ 584 if (qib_super == NULL) 585 ret = 0; 586 else 587 ret = add_cntr_files(qib_super, dd); 588 return ret; 589} 590 591int qibfs_remove(struct qib_devdata *dd) 592{ 593 int ret = 0; 594 595 if (qib_super) 596 ret = remove_device_files(qib_super, dd); 597 598 return ret; 599} 600 601static struct file_system_type qibfs_fs_type = { 602 .owner = THIS_MODULE, 603 .name = "ipathfs", 604 .get_sb = qibfs_get_sb, 605 .kill_sb = qibfs_kill_super, 606}; 607 608int __init qib_init_qibfs(void) 609{ 610 return register_filesystem(&qibfs_fs_type); 611} 612 613int __exit qib_exit_qibfs(void) 614{ 615 return unregister_filesystem(&qibfs_fs_type); 616} 617