sysfs.c (17932B)
1// SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause 2/* 3 * Copyright(c) 2015-2017 Intel Corporation. 4 */ 5 6#include <linux/ctype.h> 7#include <rdma/ib_sysfs.h> 8 9#include "hfi.h" 10#include "mad.h" 11#include "trace.h" 12 13static struct hfi1_pportdata *hfi1_get_pportdata_kobj(struct kobject *kobj) 14{ 15 u32 port_num; 16 struct ib_device *ibdev = ib_port_sysfs_get_ibdev_kobj(kobj, &port_num); 17 struct hfi1_devdata *dd = dd_from_ibdev(ibdev); 18 19 return &dd->pport[port_num - 1]; 20} 21 22/* 23 * Start of per-port congestion control structures and support code 24 */ 25 26/* 27 * Congestion control table size followed by table entries 28 */ 29static ssize_t cc_table_bin_read(struct file *filp, struct kobject *kobj, 30 struct bin_attribute *bin_attr, char *buf, 31 loff_t pos, size_t count) 32{ 33 int ret; 34 struct hfi1_pportdata *ppd = hfi1_get_pportdata_kobj(kobj); 35 struct cc_state *cc_state; 36 37 ret = ppd->total_cct_entry * sizeof(struct ib_cc_table_entry_shadow) 38 + sizeof(__be16); 39 40 if (pos > ret) 41 return -EINVAL; 42 43 if (count > ret - pos) 44 count = ret - pos; 45 46 if (!count) 47 return count; 48 49 rcu_read_lock(); 50 cc_state = get_cc_state(ppd); 51 if (!cc_state) { 52 rcu_read_unlock(); 53 return -EINVAL; 54 } 55 memcpy(buf, (void *)&cc_state->cct + pos, count); 56 rcu_read_unlock(); 57 58 return count; 59} 60static BIN_ATTR_RO(cc_table_bin, PAGE_SIZE); 61 62/* 63 * Congestion settings: port control, control map and an array of 16 64 * entries for the congestion entries - increase, timer, event log 65 * trigger threshold and the minimum injection rate delay. 66 */ 67static ssize_t cc_setting_bin_read(struct file *filp, struct kobject *kobj, 68 struct bin_attribute *bin_attr, 69 char *buf, loff_t pos, size_t count) 70{ 71 struct hfi1_pportdata *ppd = hfi1_get_pportdata_kobj(kobj); 72 int ret; 73 struct cc_state *cc_state; 74 75 ret = sizeof(struct opa_congestion_setting_attr_shadow); 76 77 if (pos > ret) 78 return -EINVAL; 79 if (count > ret - pos) 80 count = ret - pos; 81 82 if (!count) 83 return count; 84 85 rcu_read_lock(); 86 cc_state = get_cc_state(ppd); 87 if (!cc_state) { 88 rcu_read_unlock(); 89 return -EINVAL; 90 } 91 memcpy(buf, (void *)&cc_state->cong_setting + pos, count); 92 rcu_read_unlock(); 93 94 return count; 95} 96static BIN_ATTR_RO(cc_setting_bin, PAGE_SIZE); 97 98static struct bin_attribute *port_cc_bin_attributes[] = { 99 &bin_attr_cc_setting_bin, 100 &bin_attr_cc_table_bin, 101 NULL 102}; 103 104static ssize_t cc_prescan_show(struct ib_device *ibdev, u32 port_num, 105 struct ib_port_attribute *attr, char *buf) 106{ 107 struct hfi1_devdata *dd = dd_from_ibdev(ibdev); 108 struct hfi1_pportdata *ppd = &dd->pport[port_num - 1]; 109 110 return sysfs_emit(buf, "%s\n", ppd->cc_prescan ? "on" : "off"); 111} 112 113static ssize_t cc_prescan_store(struct ib_device *ibdev, u32 port_num, 114 struct ib_port_attribute *attr, const char *buf, 115 size_t count) 116{ 117 struct hfi1_devdata *dd = dd_from_ibdev(ibdev); 118 struct hfi1_pportdata *ppd = &dd->pport[port_num - 1]; 119 120 if (!memcmp(buf, "on", 2)) 121 ppd->cc_prescan = true; 122 else if (!memcmp(buf, "off", 3)) 123 ppd->cc_prescan = false; 124 125 return count; 126} 127static IB_PORT_ATTR_ADMIN_RW(cc_prescan); 128 129static struct attribute *port_cc_attributes[] = { 130 &ib_port_attr_cc_prescan.attr, 131 NULL 132}; 133 134static const struct attribute_group port_cc_group = { 135 .name = "CCMgtA", 136 .attrs = port_cc_attributes, 137 .bin_attrs = port_cc_bin_attributes, 138}; 139 140/* Start sc2vl */ 141struct hfi1_sc2vl_attr { 142 struct ib_port_attribute attr; 143 int sc; 144}; 145 146static ssize_t sc2vl_attr_show(struct ib_device *ibdev, u32 port_num, 147 struct ib_port_attribute *attr, char *buf) 148{ 149 struct hfi1_sc2vl_attr *sattr = 150 container_of(attr, struct hfi1_sc2vl_attr, attr); 151 struct hfi1_devdata *dd = dd_from_ibdev(ibdev); 152 153 return sysfs_emit(buf, "%u\n", *((u8 *)dd->sc2vl + sattr->sc)); 154} 155 156#define HFI1_SC2VL_ATTR(N) \ 157 static struct hfi1_sc2vl_attr hfi1_sc2vl_attr_##N = { \ 158 .attr = __ATTR(N, 0444, sc2vl_attr_show, NULL), \ 159 .sc = N, \ 160 } 161 162HFI1_SC2VL_ATTR(0); 163HFI1_SC2VL_ATTR(1); 164HFI1_SC2VL_ATTR(2); 165HFI1_SC2VL_ATTR(3); 166HFI1_SC2VL_ATTR(4); 167HFI1_SC2VL_ATTR(5); 168HFI1_SC2VL_ATTR(6); 169HFI1_SC2VL_ATTR(7); 170HFI1_SC2VL_ATTR(8); 171HFI1_SC2VL_ATTR(9); 172HFI1_SC2VL_ATTR(10); 173HFI1_SC2VL_ATTR(11); 174HFI1_SC2VL_ATTR(12); 175HFI1_SC2VL_ATTR(13); 176HFI1_SC2VL_ATTR(14); 177HFI1_SC2VL_ATTR(15); 178HFI1_SC2VL_ATTR(16); 179HFI1_SC2VL_ATTR(17); 180HFI1_SC2VL_ATTR(18); 181HFI1_SC2VL_ATTR(19); 182HFI1_SC2VL_ATTR(20); 183HFI1_SC2VL_ATTR(21); 184HFI1_SC2VL_ATTR(22); 185HFI1_SC2VL_ATTR(23); 186HFI1_SC2VL_ATTR(24); 187HFI1_SC2VL_ATTR(25); 188HFI1_SC2VL_ATTR(26); 189HFI1_SC2VL_ATTR(27); 190HFI1_SC2VL_ATTR(28); 191HFI1_SC2VL_ATTR(29); 192HFI1_SC2VL_ATTR(30); 193HFI1_SC2VL_ATTR(31); 194 195static struct attribute *port_sc2vl_attributes[] = { 196 &hfi1_sc2vl_attr_0.attr.attr, 197 &hfi1_sc2vl_attr_1.attr.attr, 198 &hfi1_sc2vl_attr_2.attr.attr, 199 &hfi1_sc2vl_attr_3.attr.attr, 200 &hfi1_sc2vl_attr_4.attr.attr, 201 &hfi1_sc2vl_attr_5.attr.attr, 202 &hfi1_sc2vl_attr_6.attr.attr, 203 &hfi1_sc2vl_attr_7.attr.attr, 204 &hfi1_sc2vl_attr_8.attr.attr, 205 &hfi1_sc2vl_attr_9.attr.attr, 206 &hfi1_sc2vl_attr_10.attr.attr, 207 &hfi1_sc2vl_attr_11.attr.attr, 208 &hfi1_sc2vl_attr_12.attr.attr, 209 &hfi1_sc2vl_attr_13.attr.attr, 210 &hfi1_sc2vl_attr_14.attr.attr, 211 &hfi1_sc2vl_attr_15.attr.attr, 212 &hfi1_sc2vl_attr_16.attr.attr, 213 &hfi1_sc2vl_attr_17.attr.attr, 214 &hfi1_sc2vl_attr_18.attr.attr, 215 &hfi1_sc2vl_attr_19.attr.attr, 216 &hfi1_sc2vl_attr_20.attr.attr, 217 &hfi1_sc2vl_attr_21.attr.attr, 218 &hfi1_sc2vl_attr_22.attr.attr, 219 &hfi1_sc2vl_attr_23.attr.attr, 220 &hfi1_sc2vl_attr_24.attr.attr, 221 &hfi1_sc2vl_attr_25.attr.attr, 222 &hfi1_sc2vl_attr_26.attr.attr, 223 &hfi1_sc2vl_attr_27.attr.attr, 224 &hfi1_sc2vl_attr_28.attr.attr, 225 &hfi1_sc2vl_attr_29.attr.attr, 226 &hfi1_sc2vl_attr_30.attr.attr, 227 &hfi1_sc2vl_attr_31.attr.attr, 228 NULL 229}; 230 231static const struct attribute_group port_sc2vl_group = { 232 .name = "sc2vl", 233 .attrs = port_sc2vl_attributes, 234}; 235/* End sc2vl */ 236 237/* Start sl2sc */ 238struct hfi1_sl2sc_attr { 239 struct ib_port_attribute attr; 240 int sl; 241}; 242 243static ssize_t sl2sc_attr_show(struct ib_device *ibdev, u32 port_num, 244 struct ib_port_attribute *attr, char *buf) 245{ 246 struct hfi1_sl2sc_attr *sattr = 247 container_of(attr, struct hfi1_sl2sc_attr, attr); 248 struct hfi1_devdata *dd = dd_from_ibdev(ibdev); 249 struct hfi1_ibport *ibp = &dd->pport[port_num - 1].ibport_data; 250 251 return sysfs_emit(buf, "%u\n", ibp->sl_to_sc[sattr->sl]); 252} 253 254#define HFI1_SL2SC_ATTR(N) \ 255 static struct hfi1_sl2sc_attr hfi1_sl2sc_attr_##N = { \ 256 .attr = __ATTR(N, 0444, sl2sc_attr_show, NULL), .sl = N \ 257 } 258 259HFI1_SL2SC_ATTR(0); 260HFI1_SL2SC_ATTR(1); 261HFI1_SL2SC_ATTR(2); 262HFI1_SL2SC_ATTR(3); 263HFI1_SL2SC_ATTR(4); 264HFI1_SL2SC_ATTR(5); 265HFI1_SL2SC_ATTR(6); 266HFI1_SL2SC_ATTR(7); 267HFI1_SL2SC_ATTR(8); 268HFI1_SL2SC_ATTR(9); 269HFI1_SL2SC_ATTR(10); 270HFI1_SL2SC_ATTR(11); 271HFI1_SL2SC_ATTR(12); 272HFI1_SL2SC_ATTR(13); 273HFI1_SL2SC_ATTR(14); 274HFI1_SL2SC_ATTR(15); 275HFI1_SL2SC_ATTR(16); 276HFI1_SL2SC_ATTR(17); 277HFI1_SL2SC_ATTR(18); 278HFI1_SL2SC_ATTR(19); 279HFI1_SL2SC_ATTR(20); 280HFI1_SL2SC_ATTR(21); 281HFI1_SL2SC_ATTR(22); 282HFI1_SL2SC_ATTR(23); 283HFI1_SL2SC_ATTR(24); 284HFI1_SL2SC_ATTR(25); 285HFI1_SL2SC_ATTR(26); 286HFI1_SL2SC_ATTR(27); 287HFI1_SL2SC_ATTR(28); 288HFI1_SL2SC_ATTR(29); 289HFI1_SL2SC_ATTR(30); 290HFI1_SL2SC_ATTR(31); 291 292static struct attribute *port_sl2sc_attributes[] = { 293 &hfi1_sl2sc_attr_0.attr.attr, 294 &hfi1_sl2sc_attr_1.attr.attr, 295 &hfi1_sl2sc_attr_2.attr.attr, 296 &hfi1_sl2sc_attr_3.attr.attr, 297 &hfi1_sl2sc_attr_4.attr.attr, 298 &hfi1_sl2sc_attr_5.attr.attr, 299 &hfi1_sl2sc_attr_6.attr.attr, 300 &hfi1_sl2sc_attr_7.attr.attr, 301 &hfi1_sl2sc_attr_8.attr.attr, 302 &hfi1_sl2sc_attr_9.attr.attr, 303 &hfi1_sl2sc_attr_10.attr.attr, 304 &hfi1_sl2sc_attr_11.attr.attr, 305 &hfi1_sl2sc_attr_12.attr.attr, 306 &hfi1_sl2sc_attr_13.attr.attr, 307 &hfi1_sl2sc_attr_14.attr.attr, 308 &hfi1_sl2sc_attr_15.attr.attr, 309 &hfi1_sl2sc_attr_16.attr.attr, 310 &hfi1_sl2sc_attr_17.attr.attr, 311 &hfi1_sl2sc_attr_18.attr.attr, 312 &hfi1_sl2sc_attr_19.attr.attr, 313 &hfi1_sl2sc_attr_20.attr.attr, 314 &hfi1_sl2sc_attr_21.attr.attr, 315 &hfi1_sl2sc_attr_22.attr.attr, 316 &hfi1_sl2sc_attr_23.attr.attr, 317 &hfi1_sl2sc_attr_24.attr.attr, 318 &hfi1_sl2sc_attr_25.attr.attr, 319 &hfi1_sl2sc_attr_26.attr.attr, 320 &hfi1_sl2sc_attr_27.attr.attr, 321 &hfi1_sl2sc_attr_28.attr.attr, 322 &hfi1_sl2sc_attr_29.attr.attr, 323 &hfi1_sl2sc_attr_30.attr.attr, 324 &hfi1_sl2sc_attr_31.attr.attr, 325 NULL 326}; 327 328static const struct attribute_group port_sl2sc_group = { 329 .name = "sl2sc", 330 .attrs = port_sl2sc_attributes, 331}; 332 333/* End sl2sc */ 334 335/* Start vl2mtu */ 336 337struct hfi1_vl2mtu_attr { 338 struct ib_port_attribute attr; 339 int vl; 340}; 341 342static ssize_t vl2mtu_attr_show(struct ib_device *ibdev, u32 port_num, 343 struct ib_port_attribute *attr, char *buf) 344{ 345 struct hfi1_vl2mtu_attr *vlattr = 346 container_of(attr, struct hfi1_vl2mtu_attr, attr); 347 struct hfi1_devdata *dd = dd_from_ibdev(ibdev); 348 349 return sysfs_emit(buf, "%u\n", dd->vld[vlattr->vl].mtu); 350} 351 352#define HFI1_VL2MTU_ATTR(N) \ 353 static struct hfi1_vl2mtu_attr hfi1_vl2mtu_attr_##N = { \ 354 .attr = __ATTR(N, 0444, vl2mtu_attr_show, NULL), \ 355 .vl = N, \ 356 } 357 358HFI1_VL2MTU_ATTR(0); 359HFI1_VL2MTU_ATTR(1); 360HFI1_VL2MTU_ATTR(2); 361HFI1_VL2MTU_ATTR(3); 362HFI1_VL2MTU_ATTR(4); 363HFI1_VL2MTU_ATTR(5); 364HFI1_VL2MTU_ATTR(6); 365HFI1_VL2MTU_ATTR(7); 366HFI1_VL2MTU_ATTR(8); 367HFI1_VL2MTU_ATTR(9); 368HFI1_VL2MTU_ATTR(10); 369HFI1_VL2MTU_ATTR(11); 370HFI1_VL2MTU_ATTR(12); 371HFI1_VL2MTU_ATTR(13); 372HFI1_VL2MTU_ATTR(14); 373HFI1_VL2MTU_ATTR(15); 374 375static struct attribute *port_vl2mtu_attributes[] = { 376 &hfi1_vl2mtu_attr_0.attr.attr, 377 &hfi1_vl2mtu_attr_1.attr.attr, 378 &hfi1_vl2mtu_attr_2.attr.attr, 379 &hfi1_vl2mtu_attr_3.attr.attr, 380 &hfi1_vl2mtu_attr_4.attr.attr, 381 &hfi1_vl2mtu_attr_5.attr.attr, 382 &hfi1_vl2mtu_attr_6.attr.attr, 383 &hfi1_vl2mtu_attr_7.attr.attr, 384 &hfi1_vl2mtu_attr_8.attr.attr, 385 &hfi1_vl2mtu_attr_9.attr.attr, 386 &hfi1_vl2mtu_attr_10.attr.attr, 387 &hfi1_vl2mtu_attr_11.attr.attr, 388 &hfi1_vl2mtu_attr_12.attr.attr, 389 &hfi1_vl2mtu_attr_13.attr.attr, 390 &hfi1_vl2mtu_attr_14.attr.attr, 391 &hfi1_vl2mtu_attr_15.attr.attr, 392 NULL 393}; 394 395static const struct attribute_group port_vl2mtu_group = { 396 .name = "vl2mtu", 397 .attrs = port_vl2mtu_attributes, 398}; 399 400/* end of per-port file structures and support code */ 401 402/* 403 * Start of per-unit (or driver, in some cases, but replicated 404 * per unit) functions (these get a device *) 405 */ 406static ssize_t hw_rev_show(struct device *device, struct device_attribute *attr, 407 char *buf) 408{ 409 struct hfi1_ibdev *dev = 410 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 411 412 return sysfs_emit(buf, "%x\n", dd_from_dev(dev)->minrev); 413} 414static DEVICE_ATTR_RO(hw_rev); 415 416static ssize_t board_id_show(struct device *device, 417 struct device_attribute *attr, char *buf) 418{ 419 struct hfi1_ibdev *dev = 420 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 421 struct hfi1_devdata *dd = dd_from_dev(dev); 422 423 if (!dd->boardname) 424 return -EINVAL; 425 426 return sysfs_emit(buf, "%s\n", dd->boardname); 427} 428static DEVICE_ATTR_RO(board_id); 429 430static ssize_t boardversion_show(struct device *device, 431 struct device_attribute *attr, char *buf) 432{ 433 struct hfi1_ibdev *dev = 434 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 435 struct hfi1_devdata *dd = dd_from_dev(dev); 436 437 /* The string printed here is already newline-terminated. */ 438 return sysfs_emit(buf, "%s", dd->boardversion); 439} 440static DEVICE_ATTR_RO(boardversion); 441 442static ssize_t nctxts_show(struct device *device, 443 struct device_attribute *attr, char *buf) 444{ 445 struct hfi1_ibdev *dev = 446 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 447 struct hfi1_devdata *dd = dd_from_dev(dev); 448 449 /* 450 * Return the smaller of send and receive contexts. 451 * Normally, user level applications would require both a send 452 * and a receive context, so returning the smaller of the two counts 453 * give a more accurate picture of total contexts available. 454 */ 455 return sysfs_emit(buf, "%u\n", 456 min(dd->num_user_contexts, 457 (u32)dd->sc_sizes[SC_USER].count)); 458} 459static DEVICE_ATTR_RO(nctxts); 460 461static ssize_t nfreectxts_show(struct device *device, 462 struct device_attribute *attr, char *buf) 463{ 464 struct hfi1_ibdev *dev = 465 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 466 struct hfi1_devdata *dd = dd_from_dev(dev); 467 468 /* Return the number of free user ports (contexts) available. */ 469 return sysfs_emit(buf, "%u\n", dd->freectxts); 470} 471static DEVICE_ATTR_RO(nfreectxts); 472 473static ssize_t serial_show(struct device *device, 474 struct device_attribute *attr, char *buf) 475{ 476 struct hfi1_ibdev *dev = 477 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 478 struct hfi1_devdata *dd = dd_from_dev(dev); 479 480 /* dd->serial is already newline terminated in chip.c */ 481 return sysfs_emit(buf, "%s", dd->serial); 482} 483static DEVICE_ATTR_RO(serial); 484 485static ssize_t chip_reset_store(struct device *device, 486 struct device_attribute *attr, const char *buf, 487 size_t count) 488{ 489 struct hfi1_ibdev *dev = 490 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 491 struct hfi1_devdata *dd = dd_from_dev(dev); 492 int ret; 493 494 if (count < 5 || memcmp(buf, "reset", 5) || !dd->diag_client) { 495 ret = -EINVAL; 496 goto bail; 497 } 498 499 ret = hfi1_reset_device(dd->unit); 500bail: 501 return ret < 0 ? ret : count; 502} 503static DEVICE_ATTR_WO(chip_reset); 504 505/* 506 * Convert the reported temperature from an integer (reported in 507 * units of 0.25C) to a floating point number. 508 */ 509#define temp_d(t) ((t) >> 2) 510#define temp_f(t) (((t)&0x3) * 25u) 511 512/* 513 * Dump tempsense values, in decimal, to ease shell-scripts. 514 */ 515static ssize_t tempsense_show(struct device *device, 516 struct device_attribute *attr, char *buf) 517{ 518 struct hfi1_ibdev *dev = 519 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 520 struct hfi1_devdata *dd = dd_from_dev(dev); 521 struct hfi1_temp temp; 522 int ret; 523 524 ret = hfi1_tempsense_rd(dd, &temp); 525 if (ret) 526 return ret; 527 528 return sysfs_emit(buf, "%u.%02u %u.%02u %u.%02u %u.%02u %u %u %u\n", 529 temp_d(temp.curr), temp_f(temp.curr), 530 temp_d(temp.lo_lim), temp_f(temp.lo_lim), 531 temp_d(temp.hi_lim), temp_f(temp.hi_lim), 532 temp_d(temp.crit_lim), temp_f(temp.crit_lim), 533 temp.triggers & 0x1, 534 temp.triggers & 0x2, 535 temp.triggers & 0x4); 536} 537static DEVICE_ATTR_RO(tempsense); 538 539/* 540 * end of per-unit (or driver, in some cases, but replicated 541 * per unit) functions 542 */ 543 544/* start of per-unit file structures and support code */ 545static struct attribute *hfi1_attributes[] = { 546 &dev_attr_hw_rev.attr, 547 &dev_attr_board_id.attr, 548 &dev_attr_nctxts.attr, 549 &dev_attr_nfreectxts.attr, 550 &dev_attr_serial.attr, 551 &dev_attr_boardversion.attr, 552 &dev_attr_tempsense.attr, 553 &dev_attr_chip_reset.attr, 554 NULL, 555}; 556 557const struct attribute_group ib_hfi1_attr_group = { 558 .attrs = hfi1_attributes, 559}; 560 561const struct attribute_group *hfi1_attr_port_groups[] = { 562 &port_cc_group, 563 &port_sc2vl_group, 564 &port_sl2sc_group, 565 &port_vl2mtu_group, 566 NULL, 567}; 568 569struct sde_attribute { 570 struct attribute attr; 571 ssize_t (*show)(struct sdma_engine *sde, char *buf); 572 ssize_t (*store)(struct sdma_engine *sde, const char *buf, size_t cnt); 573}; 574 575static ssize_t sde_show(struct kobject *kobj, struct attribute *attr, char *buf) 576{ 577 struct sde_attribute *sde_attr = 578 container_of(attr, struct sde_attribute, attr); 579 struct sdma_engine *sde = 580 container_of(kobj, struct sdma_engine, kobj); 581 582 if (!sde_attr->show) 583 return -EINVAL; 584 585 return sde_attr->show(sde, buf); 586} 587 588static ssize_t sde_store(struct kobject *kobj, struct attribute *attr, 589 const char *buf, size_t count) 590{ 591 struct sde_attribute *sde_attr = 592 container_of(attr, struct sde_attribute, attr); 593 struct sdma_engine *sde = 594 container_of(kobj, struct sdma_engine, kobj); 595 596 if (!capable(CAP_SYS_ADMIN)) 597 return -EPERM; 598 599 if (!sde_attr->store) 600 return -EINVAL; 601 602 return sde_attr->store(sde, buf, count); 603} 604 605static const struct sysfs_ops sde_sysfs_ops = { 606 .show = sde_show, 607 .store = sde_store, 608}; 609 610static struct kobj_type sde_ktype = { 611 .sysfs_ops = &sde_sysfs_ops, 612}; 613 614#define SDE_ATTR(_name, _mode, _show, _store) \ 615 struct sde_attribute sde_attr_##_name = \ 616 __ATTR(_name, _mode, _show, _store) 617 618static ssize_t sde_show_cpu_to_sde_map(struct sdma_engine *sde, char *buf) 619{ 620 return sdma_get_cpu_to_sde_map(sde, buf); 621} 622 623static ssize_t sde_store_cpu_to_sde_map(struct sdma_engine *sde, 624 const char *buf, size_t count) 625{ 626 return sdma_set_cpu_to_sde_map(sde, buf, count); 627} 628 629static ssize_t sde_show_vl(struct sdma_engine *sde, char *buf) 630{ 631 int vl; 632 633 vl = sdma_engine_get_vl(sde); 634 if (vl < 0) 635 return vl; 636 637 return sysfs_emit(buf, "%d\n", vl); 638} 639 640static SDE_ATTR(cpu_list, S_IWUSR | S_IRUGO, 641 sde_show_cpu_to_sde_map, 642 sde_store_cpu_to_sde_map); 643static SDE_ATTR(vl, S_IRUGO, sde_show_vl, NULL); 644 645static struct sde_attribute *sde_attribs[] = { 646 &sde_attr_cpu_list, 647 &sde_attr_vl 648}; 649 650/* 651 * Register and create our files in /sys/class/infiniband. 652 */ 653int hfi1_verbs_register_sysfs(struct hfi1_devdata *dd) 654{ 655 struct ib_device *dev = &dd->verbs_dev.rdi.ibdev; 656 struct device *class_dev = &dev->dev; 657 int i, j, ret; 658 659 for (i = 0; i < dd->num_sdma; i++) { 660 ret = kobject_init_and_add(&dd->per_sdma[i].kobj, 661 &sde_ktype, &class_dev->kobj, 662 "sdma%d", i); 663 if (ret) 664 goto bail; 665 666 for (j = 0; j < ARRAY_SIZE(sde_attribs); j++) { 667 ret = sysfs_create_file(&dd->per_sdma[i].kobj, 668 &sde_attribs[j]->attr); 669 if (ret) 670 goto bail; 671 } 672 } 673 674 return 0; 675bail: 676 /* 677 * The function kobject_put() will call kobject_del() if the kobject 678 * has been added successfully. The sysfs files created under the 679 * kobject directory will also be removed during the process. 680 */ 681 for (; i >= 0; i--) 682 kobject_put(&dd->per_sdma[i].kobj); 683 684 return ret; 685} 686 687/* 688 * Unregister and remove our files in /sys/class/infiniband. 689 */ 690void hfi1_verbs_unregister_sysfs(struct hfi1_devdata *dd) 691{ 692 int i; 693 694 /* Unwind operations in hfi1_verbs_register_sysfs() */ 695 for (i = 0; i < dd->num_sdma; i++) 696 kobject_put(&dd->per_sdma[i].kobj); 697}