1 /* 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 * 32 * $Id: sysfs.c 1349 2004-12-16 21:09:43Z roland $ 33 */ 34 35 #include "core_priv.h" 36 37 #include <ib_mad.h> 38 39 struct ib_port { 40 struct kobject kobj; 41 struct ib_device *ibdev; 42 struct attribute_group gid_group; 43 struct attribute_group pkey_group; 44 u8 port_num; 45 }; 46 47 struct port_attribute { 48 struct attribute attr; 49 ssize_t (*show)(struct ib_port *, struct port_attribute *, char *buf); 50 ssize_t (*store)(struct ib_port *, struct port_attribute *, 51 const char *buf, size_t count); 52 }; 53 54 #define PORT_ATTR(_name, _mode, _show, _store) \ 55 struct port_attribute port_attr_##_name = __ATTR(_name, _mode, _show, _store) 56 57 #define PORT_ATTR_RO(_name) \ 58 struct port_attribute port_attr_##_name = __ATTR_RO(_name) 59 60 struct port_table_attribute { 61 struct port_attribute attr; 62 char name[8]; 63 int index; 64 }; 65 66 static ssize_t port_attr_show(struct kobject *kobj, 67 struct attribute *attr, char *buf) 68 { 69 struct port_attribute *port_attr = 70 container_of(attr, struct port_attribute, attr); 71 struct ib_port *p = container_of(kobj, struct ib_port, kobj); 72 73 if (!port_attr->show) 74 return -EIO; 75 76 return port_attr->show(p, port_attr, buf); 77 } 78 79 static struct sysfs_ops port_sysfs_ops = { 80 .show = port_attr_show 81 }; 82 83 static ssize_t state_show(struct ib_port *p, struct port_attribute *unused, 84 char *buf) 85 { 86 struct ib_port_attr attr; 87 ssize_t ret; 88 89 static const char *state_name[] = { 90 [IB_PORT_NOP] = "NOP", 91 [IB_PORT_DOWN] = "DOWN", 92 [IB_PORT_INIT] = "INIT", 93 [IB_PORT_ARMED] = "ARMED", 94 [IB_PORT_ACTIVE] = "ACTIVE", 95 [IB_PORT_ACTIVE_DEFER] = "ACTIVE_DEFER" 96 }; 97 98 ret = ib_query_port(p->ibdev, p->port_num, &attr); 99 if (ret) 100 return ret; 101 102 return sprintf(buf, "%d: %s\n", attr.state, 103 attr.state >= 0 && attr.state <= ARRAY_SIZE(state_name) ? 104 state_name[attr.state] : "UNKNOWN"); 105 } 106 107 static ssize_t lid_show(struct ib_port *p, struct port_attribute *unused, 108 char *buf) 109 { 110 struct ib_port_attr attr; 111 ssize_t ret; 112 113 ret = ib_query_port(p->ibdev, p->port_num, &attr); 114 if (ret) 115 return ret; 116 117 return sprintf(buf, "0x%x\n", attr.lid); 118 } 119 120 static ssize_t lid_mask_count_show(struct ib_port *p, 121 struct port_attribute *unused, 122 char *buf) 123 { 124 struct ib_port_attr attr; 125 ssize_t ret; 126 127 ret = ib_query_port(p->ibdev, p->port_num, &attr); 128 if (ret) 129 return ret; 130 131 return sprintf(buf, "%d\n", attr.lmc); 132 } 133 134 static ssize_t sm_lid_show(struct ib_port *p, struct port_attribute *unused, 135 char *buf) 136 { 137 struct ib_port_attr attr; 138 ssize_t ret; 139 140 ret = ib_query_port(p->ibdev, p->port_num, &attr); 141 if (ret) 142 return ret; 143 144 return sprintf(buf, "0x%x\n", attr.sm_lid); 145 } 146 147 static ssize_t sm_sl_show(struct ib_port *p, struct port_attribute *unused, 148 char *buf) 149 { 150 struct ib_port_attr attr; 151 ssize_t ret; 152 153 ret = ib_query_port(p->ibdev, p->port_num, &attr); 154 if (ret) 155 return ret; 156 157 return sprintf(buf, "%d\n", attr.sm_sl); 158 } 159 160 static ssize_t cap_mask_show(struct ib_port *p, struct port_attribute *unused, 161 char *buf) 162 { 163 struct ib_port_attr attr; 164 ssize_t ret; 165 166 ret = ib_query_port(p->ibdev, p->port_num, &attr); 167 if (ret) 168 return ret; 169 170 return sprintf(buf, "0x%08x\n", attr.port_cap_flags); 171 } 172 173 static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused, 174 char *buf) 175 { 176 struct ib_port_attr attr; 177 char *speed = ""; 178 int rate; 179 ssize_t ret; 180 181 ret = ib_query_port(p->ibdev, p->port_num, &attr); 182 if (ret) 183 return ret; 184 185 switch (attr.active_speed) { 186 case 2: speed = " DDR"; break; 187 case 4: speed = " QDR"; break; 188 } 189 190 rate = 25 * ib_width_enum_to_int(attr.active_width) * attr.active_speed; 191 if (rate < 0) 192 return -EINVAL; 193 194 return sprintf(buf, "%d%s Gb/sec (%dX%s)\n", 195 rate / 10, rate % 10 ? ".5" : "", 196 ib_width_enum_to_int(attr.active_width), speed); 197 } 198 199 static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused, 200 char *buf) 201 { 202 struct ib_port_attr attr; 203 204 ssize_t ret; 205 206 ret = ib_query_port(p->ibdev, p->port_num, &attr); 207 if (ret) 208 return ret; 209 210 switch (attr.phys_state) { 211 case 1: return sprintf(buf, "1: Sleep\n"); 212 case 2: return sprintf(buf, "2: Polling\n"); 213 case 3: return sprintf(buf, "3: Disabled\n"); 214 case 4: return sprintf(buf, "4: PortConfigurationTraining\n"); 215 case 5: return sprintf(buf, "5: LinkUp\n"); 216 case 6: return sprintf(buf, "6: LinkErrorRecovery\n"); 217 case 7: return sprintf(buf, "7: Phy Test\n"); 218 default: return sprintf(buf, "%d: <unknown>\n", attr.phys_state); 219 } 220 } 221 222 static PORT_ATTR_RO(state); 223 static PORT_ATTR_RO(lid); 224 static PORT_ATTR_RO(lid_mask_count); 225 static PORT_ATTR_RO(sm_lid); 226 static PORT_ATTR_RO(sm_sl); 227 static PORT_ATTR_RO(cap_mask); 228 static PORT_ATTR_RO(rate); 229 static PORT_ATTR_RO(phys_state); 230 231 static struct attribute *port_default_attrs[] = { 232 &port_attr_state.attr, 233 &port_attr_lid.attr, 234 &port_attr_lid_mask_count.attr, 235 &port_attr_sm_lid.attr, 236 &port_attr_sm_sl.attr, 237 &port_attr_cap_mask.attr, 238 &port_attr_rate.attr, 239 &port_attr_phys_state.attr, 240 NULL 241 }; 242 243 static ssize_t show_port_gid(struct ib_port *p, struct port_attribute *attr, 244 char *buf) 245 { 246 struct port_table_attribute *tab_attr = 247 container_of(attr, struct port_table_attribute, attr); 248 union ib_gid gid; 249 ssize_t ret; 250 251 ret = ib_query_gid(p->ibdev, p->port_num, tab_attr->index, &gid); 252 if (ret) 253 return ret; 254 255 return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", 256 be16_to_cpu(((u16 *) gid.raw)[0]), 257 be16_to_cpu(((u16 *) gid.raw)[1]), 258 be16_to_cpu(((u16 *) gid.raw)[2]), 259 be16_to_cpu(((u16 *) gid.raw)[3]), 260 be16_to_cpu(((u16 *) gid.raw)[4]), 261 be16_to_cpu(((u16 *) gid.raw)[5]), 262 be16_to_cpu(((u16 *) gid.raw)[6]), 263 be16_to_cpu(((u16 *) gid.raw)[7])); 264 } 265 266 static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr, 267 char *buf) 268 { 269 struct port_table_attribute *tab_attr = 270 container_of(attr, struct port_table_attribute, attr); 271 u16 pkey; 272 ssize_t ret; 273 274 ret = ib_query_pkey(p->ibdev, p->port_num, tab_attr->index, &pkey); 275 if (ret) 276 return ret; 277 278 return sprintf(buf, "0x%04x\n", pkey); 279 } 280 281 #define PORT_PMA_ATTR(_name, _counter, _width, _offset) \ 282 struct port_table_attribute port_pma_attr_##_name = { \ 283 .attr = __ATTR(_name, S_IRUGO, show_pma_counter, NULL), \ 284 .index = (_offset) | ((_width) << 16) | ((_counter) << 24) \ 285 } 286 287 static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr, 288 char *buf) 289 { 290 struct port_table_attribute *tab_attr = 291 container_of(attr, struct port_table_attribute, attr); 292 int offset = tab_attr->index & 0xffff; 293 int width = (tab_attr->index >> 16) & 0xff; 294 struct ib_mad *in_mad = NULL; 295 struct ib_mad *out_mad = NULL; 296 ssize_t ret; 297 298 if (!p->ibdev->process_mad) 299 return sprintf(buf, "N/A (no PMA)\n"); 300 301 in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); 302 out_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); 303 if (!in_mad || !out_mad) { 304 ret = -ENOMEM; 305 goto out; 306 } 307 308 memset(in_mad, 0, sizeof *in_mad); 309 in_mad->mad_hdr.base_version = 1; 310 in_mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_PERF_MGMT; 311 in_mad->mad_hdr.class_version = 1; 312 in_mad->mad_hdr.method = IB_MGMT_METHOD_GET; 313 in_mad->mad_hdr.attr_id = cpu_to_be16(0x12); /* PortCounters */ 314 315 in_mad->data[41] = p->port_num; /* PortSelect field */ 316 317 if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY, 318 p->port_num, NULL, NULL, in_mad, out_mad) & 319 (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) != 320 (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) { 321 ret = -EINVAL; 322 goto out; 323 } 324 325 switch (width) { 326 case 4: 327 ret = sprintf(buf, "%u\n", (out_mad->data[40 + offset / 8] >> 328 (offset % 4)) & 0xf); 329 break; 330 case 8: 331 ret = sprintf(buf, "%u\n", out_mad->data[40 + offset / 8]); 332 break; 333 case 16: 334 ret = sprintf(buf, "%u\n", 335 be16_to_cpup((u16 *)(out_mad->data + 40 + offset / 8))); 336 break; 337 case 32: 338 ret = sprintf(buf, "%u\n", 339 be32_to_cpup((u32 *)(out_mad->data + 40 + offset / 8))); 340 break; 341 default: 342 ret = 0; 343 } 344 345 out: 346 kfree(in_mad); 347 kfree(out_mad); 348 349 return ret; 350 } 351 352 static PORT_PMA_ATTR(symbol_error , 0, 16, 32); 353 static PORT_PMA_ATTR(link_error_recovery , 1, 8, 48); 354 static PORT_PMA_ATTR(link_downed , 2, 8, 56); 355 static PORT_PMA_ATTR(port_rcv_errors , 3, 16, 64); 356 static PORT_PMA_ATTR(port_rcv_remote_physical_errors, 4, 16, 80); 357 static PORT_PMA_ATTR(port_rcv_switch_relay_errors , 5, 16, 96); 358 static PORT_PMA_ATTR(port_xmit_discards , 6, 16, 112); 359 static PORT_PMA_ATTR(port_xmit_constraint_errors , 7, 8, 128); 360 static PORT_PMA_ATTR(port_rcv_constraint_errors , 8, 8, 136); 361 static PORT_PMA_ATTR(local_link_integrity_errors , 9, 4, 152); 362 static PORT_PMA_ATTR(excessive_buffer_overrun_errors, 10, 4, 156); 363 static PORT_PMA_ATTR(VL15_dropped , 11, 16, 176); 364 static PORT_PMA_ATTR(port_xmit_data , 12, 32, 192); 365 static PORT_PMA_ATTR(port_rcv_data , 13, 32, 224); 366 static PORT_PMA_ATTR(port_xmit_packets , 14, 32, 256); 367 static PORT_PMA_ATTR(port_rcv_packets , 15, 32, 288); 368 369 static struct attribute *pma_attrs[] = { 370 &port_pma_attr_symbol_error.attr.attr, 371 &port_pma_attr_link_error_recovery.attr.attr, 372 &port_pma_attr_link_downed.attr.attr, 373 &port_pma_attr_port_rcv_errors.attr.attr, 374 &port_pma_attr_port_rcv_remote_physical_errors.attr.attr, 375 &port_pma_attr_port_rcv_switch_relay_errors.attr.attr, 376 &port_pma_attr_port_xmit_discards.attr.attr, 377 &port_pma_attr_port_xmit_constraint_errors.attr.attr, 378 &port_pma_attr_port_rcv_constraint_errors.attr.attr, 379 &port_pma_attr_local_link_integrity_errors.attr.attr, 380 &port_pma_attr_excessive_buffer_overrun_errors.attr.attr, 381 &port_pma_attr_VL15_dropped.attr.attr, 382 &port_pma_attr_port_xmit_data.attr.attr, 383 &port_pma_attr_port_rcv_data.attr.attr, 384 &port_pma_attr_port_xmit_packets.attr.attr, 385 &port_pma_attr_port_rcv_packets.attr.attr, 386 NULL 387 }; 388 389 static struct attribute_group pma_group = { 390 .name = "counters", 391 .attrs = pma_attrs 392 }; 393 394 static void ib_port_release(struct kobject *kobj) 395 { 396 struct ib_port *p = container_of(kobj, struct ib_port, kobj); 397 struct attribute *a; 398 int i; 399 400 for (i = 0; (a = p->gid_group.attrs[i]); ++i) 401 kfree(a); 402 403 kfree(p->gid_group.attrs); 404 405 for (i = 0; (a = p->pkey_group.attrs[i]); ++i) 406 kfree(a); 407 408 kfree(p->pkey_group.attrs); 409 410 kfree(p); 411 } 412 413 static struct kobj_type port_type = { 414 .release = ib_port_release, 415 .sysfs_ops = &port_sysfs_ops, 416 .default_attrs = port_default_attrs 417 }; 418 419 static void ib_device_release(struct class_device *cdev) 420 { 421 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); 422 423 kfree(dev); 424 } 425 426 static int ib_device_hotplug(struct class_device *cdev, char **envp, 427 int num_envp, char *buf, int size) 428 { 429 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); 430 int i = 0, len = 0; 431 432 if (add_hotplug_env_var(envp, num_envp, &i, buf, size, &len, 433 "NAME=%s", dev->name)) 434 return -ENOMEM; 435 436 /* 437 * It might be nice to pass the node GUID to hotplug, but 438 * right now the only way to get it is to query the device 439 * provider, and this can crash during device removal because 440 * we are will be running after driver removal has started. 441 * We could add a node_guid field to struct ib_device, or we 442 * could just let the hotplug script read the node GUID from 443 * sysfs when devices are added. 444 */ 445 446 envp[i] = NULL; 447 return 0; 448 } 449 450 static struct attribute ** 451 alloc_group_attrs(ssize_t (*show)(struct ib_port *, 452 struct port_attribute *, char *buf), 453 int len) 454 { 455 struct attribute **tab_attr; 456 struct port_table_attribute *element; 457 int i; 458 459 tab_attr = kcalloc(1 + len, sizeof(struct attribute *), GFP_KERNEL); 460 if (!tab_attr) 461 return NULL; 462 463 for (i = 0; i < len; i++) { 464 element = kcalloc(1, sizeof(struct port_table_attribute), 465 GFP_KERNEL); 466 if (!element) 467 goto err; 468 469 if (snprintf(element->name, sizeof(element->name), 470 "%d", i) >= sizeof(element->name)) 471 goto err; 472 473 element->attr.attr.name = element->name; 474 element->attr.attr.mode = S_IRUGO; 475 element->attr.attr.owner = THIS_MODULE; 476 element->attr.show = show; 477 element->index = i; 478 479 tab_attr[i] = &element->attr.attr; 480 } 481 482 return tab_attr; 483 484 err: 485 while (--i >= 0) 486 kfree(tab_attr[i]); 487 kfree(tab_attr); 488 return NULL; 489 } 490 491 static int add_port(struct ib_device *device, int port_num) 492 { 493 struct ib_port *p; 494 struct ib_port_attr attr; 495 int i; 496 int ret; 497 498 ret = ib_query_port(device, port_num, &attr); 499 if (ret) 500 return ret; 501 502 p = kmalloc(sizeof *p, GFP_KERNEL); 503 if (!p) 504 return -ENOMEM; 505 memset(p, 0, sizeof *p); 506 507 p->ibdev = device; 508 p->port_num = port_num; 509 p->kobj.ktype = &port_type; 510 511 p->kobj.parent = kobject_get(&device->ports_parent); 512 if (!p->kobj.parent) { 513 ret = -EBUSY; 514 goto err; 515 } 516 517 ret = kobject_set_name(&p->kobj, "%d", port_num); 518 if (ret) 519 goto err_put; 520 521 ret = kobject_register(&p->kobj); 522 if (ret) 523 goto err_put; 524 525 ret = sysfs_create_group(&p->kobj, &pma_group); 526 if (ret) 527 goto err_put; 528 529 p->gid_group.name = "gids"; 530 p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len); 531 if (!p->gid_group.attrs) 532 goto err_remove_pma; 533 534 ret = sysfs_create_group(&p->kobj, &p->gid_group); 535 if (ret) 536 goto err_free_gid; 537 538 p->pkey_group.name = "pkeys"; 539 p->pkey_group.attrs = alloc_group_attrs(show_port_pkey, 540 attr.pkey_tbl_len); 541 if (!p->pkey_group.attrs) 542 goto err_remove_gid; 543 544 ret = sysfs_create_group(&p->kobj, &p->pkey_group); 545 if (ret) 546 goto err_free_pkey; 547 548 list_add_tail(&p->kobj.entry, &device->port_list); 549 550 return 0; 551 552 err_free_pkey: 553 for (i = 0; i < attr.pkey_tbl_len; ++i) 554 kfree(p->pkey_group.attrs[i]); 555 556 kfree(p->pkey_group.attrs); 557 558 err_remove_gid: 559 sysfs_remove_group(&p->kobj, &p->gid_group); 560 561 err_free_gid: 562 for (i = 0; i < attr.gid_tbl_len; ++i) 563 kfree(p->gid_group.attrs[i]); 564 565 kfree(p->gid_group.attrs); 566 567 err_remove_pma: 568 sysfs_remove_group(&p->kobj, &pma_group); 569 570 err_put: 571 kobject_put(&device->ports_parent); 572 573 err: 574 kfree(p); 575 return ret; 576 } 577 578 static ssize_t show_node_type(struct class_device *cdev, char *buf) 579 { 580 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); 581 582 switch (dev->node_type) { 583 case IB_NODE_CA: return sprintf(buf, "%d: CA\n", dev->node_type); 584 case IB_NODE_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type); 585 case IB_NODE_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type); 586 default: return sprintf(buf, "%d: <unknown>\n", dev->node_type); 587 } 588 } 589 590 static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf) 591 { 592 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); 593 struct ib_device_attr attr; 594 ssize_t ret; 595 596 ret = ib_query_device(dev, &attr); 597 if (ret) 598 return ret; 599 600 return sprintf(buf, "%04x:%04x:%04x:%04x\n", 601 be16_to_cpu(((u16 *) &attr.sys_image_guid)[0]), 602 be16_to_cpu(((u16 *) &attr.sys_image_guid)[1]), 603 be16_to_cpu(((u16 *) &attr.sys_image_guid)[2]), 604 be16_to_cpu(((u16 *) &attr.sys_image_guid)[3])); 605 } 606 607 static ssize_t show_node_guid(struct class_device *cdev, char *buf) 608 { 609 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); 610 struct ib_device_attr attr; 611 ssize_t ret; 612 613 ret = ib_query_device(dev, &attr); 614 if (ret) 615 return ret; 616 617 return sprintf(buf, "%04x:%04x:%04x:%04x\n", 618 be16_to_cpu(((u16 *) &attr.node_guid)[0]), 619 be16_to_cpu(((u16 *) &attr.node_guid)[1]), 620 be16_to_cpu(((u16 *) &attr.node_guid)[2]), 621 be16_to_cpu(((u16 *) &attr.node_guid)[3])); 622 } 623 624 static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); 625 static CLASS_DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL); 626 static CLASS_DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL); 627 628 static struct class_device_attribute *ib_class_attributes[] = { 629 &class_device_attr_node_type, 630 &class_device_attr_sys_image_guid, 631 &class_device_attr_node_guid 632 }; 633 634 static struct class ib_class = { 635 .name = "infiniband", 636 .release = ib_device_release, 637 .hotplug = ib_device_hotplug, 638 }; 639 640 int ib_device_register_sysfs(struct ib_device *device) 641 { 642 struct class_device *class_dev = &device->class_dev; 643 int ret; 644 int i; 645 646 class_dev->class = &ib_class; 647 class_dev->class_data = device; 648 strlcpy(class_dev->class_id, device->name, BUS_ID_SIZE); 649 650 INIT_LIST_HEAD(&device->port_list); 651 652 ret = class_device_register(class_dev); 653 if (ret) 654 goto err; 655 656 for (i = 0; i < ARRAY_SIZE(ib_class_attributes); ++i) { 657 ret = class_device_create_file(class_dev, ib_class_attributes[i]); 658 if (ret) 659 goto err_unregister; 660 } 661 662 device->ports_parent.parent = kobject_get(&class_dev->kobj); 663 if (!device->ports_parent.parent) { 664 ret = -EBUSY; 665 goto err_unregister; 666 } 667 ret = kobject_set_name(&device->ports_parent, "ports"); 668 if (ret) 669 goto err_put; 670 ret = kobject_register(&device->ports_parent); 671 if (ret) 672 goto err_put; 673 674 if (device->node_type == IB_NODE_SWITCH) { 675 ret = add_port(device, 0); 676 if (ret) 677 goto err_put; 678 } else { 679 int i; 680 681 for (i = 1; i <= device->phys_port_cnt; ++i) { 682 ret = add_port(device, i); 683 if (ret) 684 goto err_put; 685 } 686 } 687 688 return 0; 689 690 err_put: 691 { 692 struct kobject *p, *t; 693 struct ib_port *port; 694 695 list_for_each_entry_safe(p, t, &device->port_list, entry) { 696 list_del(&p->entry); 697 port = container_of(p, struct ib_port, kobj); 698 sysfs_remove_group(p, &pma_group); 699 sysfs_remove_group(p, &port->pkey_group); 700 sysfs_remove_group(p, &port->gid_group); 701 kobject_unregister(p); 702 } 703 } 704 705 kobject_put(&class_dev->kobj); 706 707 err_unregister: 708 class_device_unregister(class_dev); 709 710 err: 711 return ret; 712 } 713 714 void ib_device_unregister_sysfs(struct ib_device *device) 715 { 716 struct kobject *p, *t; 717 struct ib_port *port; 718 719 list_for_each_entry_safe(p, t, &device->port_list, entry) { 720 list_del(&p->entry); 721 port = container_of(p, struct ib_port, kobj); 722 sysfs_remove_group(p, &pma_group); 723 sysfs_remove_group(p, &port->pkey_group); 724 sysfs_remove_group(p, &port->gid_group); 725 kobject_unregister(p); 726 } 727 728 kobject_unregister(&device->ports_parent); 729 class_device_unregister(&device->class_dev); 730 } 731 732 int ib_sysfs_setup(void) 733 { 734 return class_register(&ib_class); 735 } 736 737 void ib_sysfs_cleanup(void) 738 { 739 class_unregister(&ib_class); 740 } 741