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