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 #include <linux/ctype.h> 34 35 #include "qib.h" 36 37 /** 38 * qib_parse_ushort - parse an unsigned short value in an arbitrary base 39 * @str: the string containing the number 40 * @valp: where to put the result 41 * 42 * Returns the number of bytes consumed, or negative value on error. 43 */ 44 static int qib_parse_ushort(const char *str, unsigned short *valp) 45 { 46 unsigned long val; 47 char *end; 48 int ret; 49 50 if (!isdigit(str[0])) { 51 ret = -EINVAL; 52 goto bail; 53 } 54 55 val = simple_strtoul(str, &end, 0); 56 57 if (val > 0xffff) { 58 ret = -EINVAL; 59 goto bail; 60 } 61 62 *valp = val; 63 64 ret = end + 1 - str; 65 if (ret == 0) 66 ret = -EINVAL; 67 68 bail: 69 return ret; 70 } 71 72 /* start of per-port functions */ 73 /* 74 * Get/Set heartbeat enable. OR of 1=enabled, 2=auto 75 */ 76 static ssize_t show_hrtbt_enb(struct qib_pportdata *ppd, char *buf) 77 { 78 struct qib_devdata *dd = ppd->dd; 79 int ret; 80 81 ret = dd->f_get_ib_cfg(ppd, QIB_IB_CFG_HRTBT); 82 ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); 83 return ret; 84 } 85 86 static ssize_t store_hrtbt_enb(struct qib_pportdata *ppd, const char *buf, 87 size_t count) 88 { 89 struct qib_devdata *dd = ppd->dd; 90 int ret; 91 u16 val; 92 93 ret = qib_parse_ushort(buf, &val); 94 95 /* 96 * Set the "intentional" heartbeat enable per either of 97 * "Enable" and "Auto", as these are normally set together. 98 * This bit is consulted when leaving loopback mode, 99 * because entering loopback mode overrides it and automatically 100 * disables heartbeat. 101 */ 102 if (ret >= 0) 103 ret = dd->f_set_ib_cfg(ppd, QIB_IB_CFG_HRTBT, val); 104 if (ret < 0) 105 qib_dev_err(dd, "attempt to set invalid Heartbeat enable\n"); 106 return ret < 0 ? ret : count; 107 } 108 109 static ssize_t store_loopback(struct qib_pportdata *ppd, const char *buf, 110 size_t count) 111 { 112 struct qib_devdata *dd = ppd->dd; 113 int ret = count, r; 114 115 r = dd->f_set_ib_loopback(ppd, buf); 116 if (r < 0) 117 ret = r; 118 119 return ret; 120 } 121 122 static ssize_t store_led_override(struct qib_pportdata *ppd, const char *buf, 123 size_t count) 124 { 125 struct qib_devdata *dd = ppd->dd; 126 int ret; 127 u16 val; 128 129 ret = qib_parse_ushort(buf, &val); 130 if (ret > 0) 131 qib_set_led_override(ppd, val); 132 else 133 qib_dev_err(dd, "attempt to set invalid LED override\n"); 134 return ret < 0 ? ret : count; 135 } 136 137 static ssize_t show_status(struct qib_pportdata *ppd, char *buf) 138 { 139 ssize_t ret; 140 141 if (!ppd->statusp) 142 ret = -EINVAL; 143 else 144 ret = scnprintf(buf, PAGE_SIZE, "0x%llx\n", 145 (unsigned long long) *(ppd->statusp)); 146 return ret; 147 } 148 149 /* 150 * For userland compatibility, these offsets must remain fixed. 151 * They are strings for QIB_STATUS_* 152 */ 153 static const char *qib_status_str[] = { 154 "Initted", 155 "", 156 "", 157 "", 158 "", 159 "Present", 160 "IB_link_up", 161 "IB_configured", 162 "", 163 "Fatal_Hardware_Error", 164 NULL, 165 }; 166 167 static ssize_t show_status_str(struct qib_pportdata *ppd, char *buf) 168 { 169 int i, any; 170 u64 s; 171 ssize_t ret; 172 173 if (!ppd->statusp) { 174 ret = -EINVAL; 175 goto bail; 176 } 177 178 s = *(ppd->statusp); 179 *buf = '\0'; 180 for (any = i = 0; s && qib_status_str[i]; i++) { 181 if (s & 1) { 182 /* if overflow */ 183 if (any && strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE) 184 break; 185 if (strlcat(buf, qib_status_str[i], PAGE_SIZE) >= 186 PAGE_SIZE) 187 break; 188 any = 1; 189 } 190 s >>= 1; 191 } 192 if (any) 193 strlcat(buf, "\n", PAGE_SIZE); 194 195 ret = strlen(buf); 196 197 bail: 198 return ret; 199 } 200 201 /* end of per-port functions */ 202 203 /* 204 * Start of per-port file structures and support code 205 * Because we are fitting into other infrastructure, we have to supply the 206 * full set of kobject/sysfs_ops structures and routines. 207 */ 208 #define QIB_PORT_ATTR(name, mode, show, store) \ 209 static struct qib_port_attr qib_port_attr_##name = \ 210 __ATTR(name, mode, show, store) 211 212 struct qib_port_attr { 213 struct attribute attr; 214 ssize_t (*show)(struct qib_pportdata *, char *); 215 ssize_t (*store)(struct qib_pportdata *, const char *, size_t); 216 }; 217 218 QIB_PORT_ATTR(loopback, S_IWUSR, NULL, store_loopback); 219 QIB_PORT_ATTR(led_override, S_IWUSR, NULL, store_led_override); 220 QIB_PORT_ATTR(hrtbt_enable, S_IWUSR | S_IRUGO, show_hrtbt_enb, 221 store_hrtbt_enb); 222 QIB_PORT_ATTR(status, S_IRUGO, show_status, NULL); 223 QIB_PORT_ATTR(status_str, S_IRUGO, show_status_str, NULL); 224 225 static struct attribute *port_default_attributes[] = { 226 &qib_port_attr_loopback.attr, 227 &qib_port_attr_led_override.attr, 228 &qib_port_attr_hrtbt_enable.attr, 229 &qib_port_attr_status.attr, 230 &qib_port_attr_status_str.attr, 231 NULL 232 }; 233 234 static ssize_t qib_portattr_show(struct kobject *kobj, 235 struct attribute *attr, char *buf) 236 { 237 struct qib_port_attr *pattr = 238 container_of(attr, struct qib_port_attr, attr); 239 struct qib_pportdata *ppd = 240 container_of(kobj, struct qib_pportdata, pport_kobj); 241 242 return pattr->show(ppd, buf); 243 } 244 245 static ssize_t qib_portattr_store(struct kobject *kobj, 246 struct attribute *attr, const char *buf, size_t len) 247 { 248 struct qib_port_attr *pattr = 249 container_of(attr, struct qib_port_attr, attr); 250 struct qib_pportdata *ppd = 251 container_of(kobj, struct qib_pportdata, pport_kobj); 252 253 return pattr->store(ppd, buf, len); 254 } 255 256 static void qib_port_release(struct kobject *kobj) 257 { 258 /* nothing to do since memory is freed by qib_free_devdata() */ 259 } 260 261 static const struct sysfs_ops qib_port_ops = { 262 .show = qib_portattr_show, 263 .store = qib_portattr_store, 264 }; 265 266 static struct kobj_type qib_port_ktype = { 267 .release = qib_port_release, 268 .sysfs_ops = &qib_port_ops, 269 .default_attrs = port_default_attributes 270 }; 271 272 /* Start sl2vl */ 273 274 #define QIB_SL2VL_ATTR(N) \ 275 static struct qib_sl2vl_attr qib_sl2vl_attr_##N = { \ 276 .attr = { .name = __stringify(N), .mode = 0444 }, \ 277 .sl = N \ 278 } 279 280 struct qib_sl2vl_attr { 281 struct attribute attr; 282 int sl; 283 }; 284 285 QIB_SL2VL_ATTR(0); 286 QIB_SL2VL_ATTR(1); 287 QIB_SL2VL_ATTR(2); 288 QIB_SL2VL_ATTR(3); 289 QIB_SL2VL_ATTR(4); 290 QIB_SL2VL_ATTR(5); 291 QIB_SL2VL_ATTR(6); 292 QIB_SL2VL_ATTR(7); 293 QIB_SL2VL_ATTR(8); 294 QIB_SL2VL_ATTR(9); 295 QIB_SL2VL_ATTR(10); 296 QIB_SL2VL_ATTR(11); 297 QIB_SL2VL_ATTR(12); 298 QIB_SL2VL_ATTR(13); 299 QIB_SL2VL_ATTR(14); 300 QIB_SL2VL_ATTR(15); 301 302 static struct attribute *sl2vl_default_attributes[] = { 303 &qib_sl2vl_attr_0.attr, 304 &qib_sl2vl_attr_1.attr, 305 &qib_sl2vl_attr_2.attr, 306 &qib_sl2vl_attr_3.attr, 307 &qib_sl2vl_attr_4.attr, 308 &qib_sl2vl_attr_5.attr, 309 &qib_sl2vl_attr_6.attr, 310 &qib_sl2vl_attr_7.attr, 311 &qib_sl2vl_attr_8.attr, 312 &qib_sl2vl_attr_9.attr, 313 &qib_sl2vl_attr_10.attr, 314 &qib_sl2vl_attr_11.attr, 315 &qib_sl2vl_attr_12.attr, 316 &qib_sl2vl_attr_13.attr, 317 &qib_sl2vl_attr_14.attr, 318 &qib_sl2vl_attr_15.attr, 319 NULL 320 }; 321 322 static ssize_t sl2vl_attr_show(struct kobject *kobj, struct attribute *attr, 323 char *buf) 324 { 325 struct qib_sl2vl_attr *sattr = 326 container_of(attr, struct qib_sl2vl_attr, attr); 327 struct qib_pportdata *ppd = 328 container_of(kobj, struct qib_pportdata, sl2vl_kobj); 329 struct qib_ibport *qibp = &ppd->ibport_data; 330 331 return sprintf(buf, "%u\n", qibp->sl_to_vl[sattr->sl]); 332 } 333 334 static const struct sysfs_ops qib_sl2vl_ops = { 335 .show = sl2vl_attr_show, 336 }; 337 338 static struct kobj_type qib_sl2vl_ktype = { 339 .release = qib_port_release, 340 .sysfs_ops = &qib_sl2vl_ops, 341 .default_attrs = sl2vl_default_attributes 342 }; 343 344 /* End sl2vl */ 345 346 /* Start diag_counters */ 347 348 #define QIB_DIAGC_ATTR(N) \ 349 static struct qib_diagc_attr qib_diagc_attr_##N = { \ 350 .attr = { .name = __stringify(N), .mode = 0664 }, \ 351 .counter = offsetof(struct qib_ibport, n_##N) \ 352 } 353 354 struct qib_diagc_attr { 355 struct attribute attr; 356 size_t counter; 357 }; 358 359 QIB_DIAGC_ATTR(rc_resends); 360 QIB_DIAGC_ATTR(rc_acks); 361 QIB_DIAGC_ATTR(rc_qacks); 362 QIB_DIAGC_ATTR(rc_delayed_comp); 363 QIB_DIAGC_ATTR(seq_naks); 364 QIB_DIAGC_ATTR(rdma_seq); 365 QIB_DIAGC_ATTR(rnr_naks); 366 QIB_DIAGC_ATTR(other_naks); 367 QIB_DIAGC_ATTR(rc_timeouts); 368 QIB_DIAGC_ATTR(loop_pkts); 369 QIB_DIAGC_ATTR(pkt_drops); 370 QIB_DIAGC_ATTR(dmawait); 371 QIB_DIAGC_ATTR(unaligned); 372 QIB_DIAGC_ATTR(rc_dupreq); 373 QIB_DIAGC_ATTR(rc_seqnak); 374 375 static struct attribute *diagc_default_attributes[] = { 376 &qib_diagc_attr_rc_resends.attr, 377 &qib_diagc_attr_rc_acks.attr, 378 &qib_diagc_attr_rc_qacks.attr, 379 &qib_diagc_attr_rc_delayed_comp.attr, 380 &qib_diagc_attr_seq_naks.attr, 381 &qib_diagc_attr_rdma_seq.attr, 382 &qib_diagc_attr_rnr_naks.attr, 383 &qib_diagc_attr_other_naks.attr, 384 &qib_diagc_attr_rc_timeouts.attr, 385 &qib_diagc_attr_loop_pkts.attr, 386 &qib_diagc_attr_pkt_drops.attr, 387 &qib_diagc_attr_dmawait.attr, 388 &qib_diagc_attr_unaligned.attr, 389 &qib_diagc_attr_rc_dupreq.attr, 390 &qib_diagc_attr_rc_seqnak.attr, 391 NULL 392 }; 393 394 static ssize_t diagc_attr_show(struct kobject *kobj, struct attribute *attr, 395 char *buf) 396 { 397 struct qib_diagc_attr *dattr = 398 container_of(attr, struct qib_diagc_attr, attr); 399 struct qib_pportdata *ppd = 400 container_of(kobj, struct qib_pportdata, diagc_kobj); 401 struct qib_ibport *qibp = &ppd->ibport_data; 402 403 return sprintf(buf, "%u\n", *(u32 *)((char *)qibp + dattr->counter)); 404 } 405 406 static ssize_t diagc_attr_store(struct kobject *kobj, struct attribute *attr, 407 const char *buf, size_t size) 408 { 409 struct qib_diagc_attr *dattr = 410 container_of(attr, struct qib_diagc_attr, attr); 411 struct qib_pportdata *ppd = 412 container_of(kobj, struct qib_pportdata, diagc_kobj); 413 struct qib_ibport *qibp = &ppd->ibport_data; 414 char *endp; 415 long val = simple_strtol(buf, &endp, 0); 416 417 if (val < 0 || endp == buf) 418 return -EINVAL; 419 420 *(u32 *)((char *) qibp + dattr->counter) = val; 421 return size; 422 } 423 424 static const struct sysfs_ops qib_diagc_ops = { 425 .show = diagc_attr_show, 426 .store = diagc_attr_store, 427 }; 428 429 static struct kobj_type qib_diagc_ktype = { 430 .release = qib_port_release, 431 .sysfs_ops = &qib_diagc_ops, 432 .default_attrs = diagc_default_attributes 433 }; 434 435 /* End diag_counters */ 436 437 /* end of per-port file structures and support code */ 438 439 /* 440 * Start of per-unit (or driver, in some cases, but replicated 441 * per unit) functions (these get a device *) 442 */ 443 static ssize_t show_rev(struct device *device, struct device_attribute *attr, 444 char *buf) 445 { 446 struct qib_ibdev *dev = 447 container_of(device, struct qib_ibdev, ibdev.dev); 448 449 return sprintf(buf, "%x\n", dd_from_dev(dev)->minrev); 450 } 451 452 static ssize_t show_hca(struct device *device, struct device_attribute *attr, 453 char *buf) 454 { 455 struct qib_ibdev *dev = 456 container_of(device, struct qib_ibdev, ibdev.dev); 457 struct qib_devdata *dd = dd_from_dev(dev); 458 int ret; 459 460 if (!dd->boardname) 461 ret = -EINVAL; 462 else 463 ret = scnprintf(buf, PAGE_SIZE, "%s\n", dd->boardname); 464 return ret; 465 } 466 467 static ssize_t show_version(struct device *device, 468 struct device_attribute *attr, char *buf) 469 { 470 /* The string printed here is already newline-terminated. */ 471 return scnprintf(buf, PAGE_SIZE, "%s", (char *)ib_qib_version); 472 } 473 474 static ssize_t show_boardversion(struct device *device, 475 struct device_attribute *attr, char *buf) 476 { 477 struct qib_ibdev *dev = 478 container_of(device, struct qib_ibdev, ibdev.dev); 479 struct qib_devdata *dd = dd_from_dev(dev); 480 481 /* The string printed here is already newline-terminated. */ 482 return scnprintf(buf, PAGE_SIZE, "%s", dd->boardversion); 483 } 484 485 486 static ssize_t show_localbus_info(struct device *device, 487 struct device_attribute *attr, char *buf) 488 { 489 struct qib_ibdev *dev = 490 container_of(device, struct qib_ibdev, ibdev.dev); 491 struct qib_devdata *dd = dd_from_dev(dev); 492 493 /* The string printed here is already newline-terminated. */ 494 return scnprintf(buf, PAGE_SIZE, "%s", dd->lbus_info); 495 } 496 497 498 static ssize_t show_nctxts(struct device *device, 499 struct device_attribute *attr, char *buf) 500 { 501 struct qib_ibdev *dev = 502 container_of(device, struct qib_ibdev, ibdev.dev); 503 struct qib_devdata *dd = dd_from_dev(dev); 504 505 /* Return the number of user ports (contexts) available. */ 506 return scnprintf(buf, PAGE_SIZE, "%u\n", dd->cfgctxts - 507 dd->first_user_ctxt); 508 } 509 510 static ssize_t show_serial(struct device *device, 511 struct device_attribute *attr, char *buf) 512 { 513 struct qib_ibdev *dev = 514 container_of(device, struct qib_ibdev, ibdev.dev); 515 struct qib_devdata *dd = dd_from_dev(dev); 516 517 buf[sizeof dd->serial] = '\0'; 518 memcpy(buf, dd->serial, sizeof dd->serial); 519 strcat(buf, "\n"); 520 return strlen(buf); 521 } 522 523 static ssize_t store_chip_reset(struct device *device, 524 struct device_attribute *attr, const char *buf, 525 size_t count) 526 { 527 struct qib_ibdev *dev = 528 container_of(device, struct qib_ibdev, ibdev.dev); 529 struct qib_devdata *dd = dd_from_dev(dev); 530 int ret; 531 532 if (count < 5 || memcmp(buf, "reset", 5) || !dd->diag_client) { 533 ret = -EINVAL; 534 goto bail; 535 } 536 537 ret = qib_reset_device(dd->unit); 538 bail: 539 return ret < 0 ? ret : count; 540 } 541 542 static ssize_t show_logged_errs(struct device *device, 543 struct device_attribute *attr, char *buf) 544 { 545 struct qib_ibdev *dev = 546 container_of(device, struct qib_ibdev, ibdev.dev); 547 struct qib_devdata *dd = dd_from_dev(dev); 548 int idx, count; 549 550 /* force consistency with actual EEPROM */ 551 if (qib_update_eeprom_log(dd) != 0) 552 return -ENXIO; 553 554 count = 0; 555 for (idx = 0; idx < QIB_EEP_LOG_CNT; ++idx) { 556 count += scnprintf(buf + count, PAGE_SIZE - count, "%d%c", 557 dd->eep_st_errs[idx], 558 idx == (QIB_EEP_LOG_CNT - 1) ? '\n' : ' '); 559 } 560 561 return count; 562 } 563 564 /* 565 * Dump tempsense regs. in decimal, to ease shell-scripts. 566 */ 567 static ssize_t show_tempsense(struct device *device, 568 struct device_attribute *attr, char *buf) 569 { 570 struct qib_ibdev *dev = 571 container_of(device, struct qib_ibdev, ibdev.dev); 572 struct qib_devdata *dd = dd_from_dev(dev); 573 int ret; 574 int idx; 575 u8 regvals[8]; 576 577 ret = -ENXIO; 578 for (idx = 0; idx < 8; ++idx) { 579 if (idx == 6) 580 continue; 581 ret = dd->f_tempsense_rd(dd, idx); 582 if (ret < 0) 583 break; 584 regvals[idx] = ret; 585 } 586 if (idx == 8) 587 ret = scnprintf(buf, PAGE_SIZE, "%d %d %02X %02X %d %d\n", 588 *(signed char *)(regvals), 589 *(signed char *)(regvals + 1), 590 regvals[2], regvals[3], 591 *(signed char *)(regvals + 5), 592 *(signed char *)(regvals + 7)); 593 return ret; 594 } 595 596 /* 597 * end of per-unit (or driver, in some cases, but replicated 598 * per unit) functions 599 */ 600 601 /* start of per-unit file structures and support code */ 602 static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); 603 static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); 604 static DEVICE_ATTR(board_id, S_IRUGO, show_hca, NULL); 605 static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); 606 static DEVICE_ATTR(nctxts, S_IRUGO, show_nctxts, NULL); 607 static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL); 608 static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL); 609 static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL); 610 static DEVICE_ATTR(tempsense, S_IRUGO, show_tempsense, NULL); 611 static DEVICE_ATTR(localbus_info, S_IRUGO, show_localbus_info, NULL); 612 static DEVICE_ATTR(chip_reset, S_IWUSR, NULL, store_chip_reset); 613 614 static struct device_attribute *qib_attributes[] = { 615 &dev_attr_hw_rev, 616 &dev_attr_hca_type, 617 &dev_attr_board_id, 618 &dev_attr_version, 619 &dev_attr_nctxts, 620 &dev_attr_serial, 621 &dev_attr_boardversion, 622 &dev_attr_logged_errors, 623 &dev_attr_tempsense, 624 &dev_attr_localbus_info, 625 &dev_attr_chip_reset, 626 }; 627 628 int qib_create_port_files(struct ib_device *ibdev, u8 port_num, 629 struct kobject *kobj) 630 { 631 struct qib_pportdata *ppd; 632 struct qib_devdata *dd = dd_from_ibdev(ibdev); 633 int ret; 634 635 if (!port_num || port_num > dd->num_pports) { 636 qib_dev_err(dd, "Skipping infiniband class with " 637 "invalid port %u\n", port_num); 638 ret = -ENODEV; 639 goto bail; 640 } 641 ppd = &dd->pport[port_num - 1]; 642 643 ret = kobject_init_and_add(&ppd->pport_kobj, &qib_port_ktype, kobj, 644 "linkcontrol"); 645 if (ret) { 646 qib_dev_err(dd, "Skipping linkcontrol sysfs info, " 647 "(err %d) port %u\n", ret, port_num); 648 goto bail; 649 } 650 kobject_uevent(&ppd->pport_kobj, KOBJ_ADD); 651 652 ret = kobject_init_and_add(&ppd->sl2vl_kobj, &qib_sl2vl_ktype, kobj, 653 "sl2vl"); 654 if (ret) { 655 qib_dev_err(dd, "Skipping sl2vl sysfs info, " 656 "(err %d) port %u\n", ret, port_num); 657 goto bail_sl; 658 } 659 kobject_uevent(&ppd->sl2vl_kobj, KOBJ_ADD); 660 661 ret = kobject_init_and_add(&ppd->diagc_kobj, &qib_diagc_ktype, kobj, 662 "diag_counters"); 663 if (ret) { 664 qib_dev_err(dd, "Skipping diag_counters sysfs info, " 665 "(err %d) port %u\n", ret, port_num); 666 goto bail_diagc; 667 } 668 kobject_uevent(&ppd->diagc_kobj, KOBJ_ADD); 669 670 return 0; 671 672 bail_diagc: 673 kobject_put(&ppd->sl2vl_kobj); 674 bail_sl: 675 kobject_put(&ppd->pport_kobj); 676 bail: 677 return ret; 678 } 679 680 /* 681 * Register and create our files in /sys/class/infiniband. 682 */ 683 int qib_verbs_register_sysfs(struct qib_devdata *dd) 684 { 685 struct ib_device *dev = &dd->verbs_dev.ibdev; 686 int i, ret; 687 688 for (i = 0; i < ARRAY_SIZE(qib_attributes); ++i) { 689 ret = device_create_file(&dev->dev, qib_attributes[i]); 690 if (ret) 691 return ret; 692 } 693 694 return 0; 695 } 696 697 /* 698 * Unregister and remove our files in /sys/class/infiniband. 699 */ 700 void qib_verbs_unregister_sysfs(struct qib_devdata *dd) 701 { 702 struct qib_pportdata *ppd; 703 int i; 704 705 for (i = 0; i < dd->num_pports; i++) { 706 ppd = &dd->pport[i]; 707 kobject_put(&ppd->pport_kobj); 708 kobject_put(&ppd->sl2vl_kobj); 709 } 710 } 711