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 13 static 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 */ 29 static 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 } 60 static 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 */ 67 static 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 } 96 static BIN_ATTR_RO(cc_setting_bin, PAGE_SIZE); 97 98 static struct bin_attribute *port_cc_bin_attributes[] = { 99 &bin_attr_cc_setting_bin, 100 &bin_attr_cc_table_bin, 101 NULL 102 }; 103 104 static 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 113 static 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 } 127 static IB_PORT_ATTR_ADMIN_RW(cc_prescan); 128 129 static struct attribute *port_cc_attributes[] = { 130 &ib_port_attr_cc_prescan.attr, 131 NULL 132 }; 133 134 static 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 */ 141 struct hfi1_sc2vl_attr { 142 struct ib_port_attribute attr; 143 int sc; 144 }; 145 146 static 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 162 HFI1_SC2VL_ATTR(0); 163 HFI1_SC2VL_ATTR(1); 164 HFI1_SC2VL_ATTR(2); 165 HFI1_SC2VL_ATTR(3); 166 HFI1_SC2VL_ATTR(4); 167 HFI1_SC2VL_ATTR(5); 168 HFI1_SC2VL_ATTR(6); 169 HFI1_SC2VL_ATTR(7); 170 HFI1_SC2VL_ATTR(8); 171 HFI1_SC2VL_ATTR(9); 172 HFI1_SC2VL_ATTR(10); 173 HFI1_SC2VL_ATTR(11); 174 HFI1_SC2VL_ATTR(12); 175 HFI1_SC2VL_ATTR(13); 176 HFI1_SC2VL_ATTR(14); 177 HFI1_SC2VL_ATTR(15); 178 HFI1_SC2VL_ATTR(16); 179 HFI1_SC2VL_ATTR(17); 180 HFI1_SC2VL_ATTR(18); 181 HFI1_SC2VL_ATTR(19); 182 HFI1_SC2VL_ATTR(20); 183 HFI1_SC2VL_ATTR(21); 184 HFI1_SC2VL_ATTR(22); 185 HFI1_SC2VL_ATTR(23); 186 HFI1_SC2VL_ATTR(24); 187 HFI1_SC2VL_ATTR(25); 188 HFI1_SC2VL_ATTR(26); 189 HFI1_SC2VL_ATTR(27); 190 HFI1_SC2VL_ATTR(28); 191 HFI1_SC2VL_ATTR(29); 192 HFI1_SC2VL_ATTR(30); 193 HFI1_SC2VL_ATTR(31); 194 195 static 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 231 static const struct attribute_group port_sc2vl_group = { 232 .name = "sc2vl", 233 .attrs = port_sc2vl_attributes, 234 }; 235 /* End sc2vl */ 236 237 /* Start sl2sc */ 238 struct hfi1_sl2sc_attr { 239 struct ib_port_attribute attr; 240 int sl; 241 }; 242 243 static 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 259 HFI1_SL2SC_ATTR(0); 260 HFI1_SL2SC_ATTR(1); 261 HFI1_SL2SC_ATTR(2); 262 HFI1_SL2SC_ATTR(3); 263 HFI1_SL2SC_ATTR(4); 264 HFI1_SL2SC_ATTR(5); 265 HFI1_SL2SC_ATTR(6); 266 HFI1_SL2SC_ATTR(7); 267 HFI1_SL2SC_ATTR(8); 268 HFI1_SL2SC_ATTR(9); 269 HFI1_SL2SC_ATTR(10); 270 HFI1_SL2SC_ATTR(11); 271 HFI1_SL2SC_ATTR(12); 272 HFI1_SL2SC_ATTR(13); 273 HFI1_SL2SC_ATTR(14); 274 HFI1_SL2SC_ATTR(15); 275 HFI1_SL2SC_ATTR(16); 276 HFI1_SL2SC_ATTR(17); 277 HFI1_SL2SC_ATTR(18); 278 HFI1_SL2SC_ATTR(19); 279 HFI1_SL2SC_ATTR(20); 280 HFI1_SL2SC_ATTR(21); 281 HFI1_SL2SC_ATTR(22); 282 HFI1_SL2SC_ATTR(23); 283 HFI1_SL2SC_ATTR(24); 284 HFI1_SL2SC_ATTR(25); 285 HFI1_SL2SC_ATTR(26); 286 HFI1_SL2SC_ATTR(27); 287 HFI1_SL2SC_ATTR(28); 288 HFI1_SL2SC_ATTR(29); 289 HFI1_SL2SC_ATTR(30); 290 HFI1_SL2SC_ATTR(31); 291 292 static 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 328 static 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 337 struct hfi1_vl2mtu_attr { 338 struct ib_port_attribute attr; 339 int vl; 340 }; 341 342 static 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 358 HFI1_VL2MTU_ATTR(0); 359 HFI1_VL2MTU_ATTR(1); 360 HFI1_VL2MTU_ATTR(2); 361 HFI1_VL2MTU_ATTR(3); 362 HFI1_VL2MTU_ATTR(4); 363 HFI1_VL2MTU_ATTR(5); 364 HFI1_VL2MTU_ATTR(6); 365 HFI1_VL2MTU_ATTR(7); 366 HFI1_VL2MTU_ATTR(8); 367 HFI1_VL2MTU_ATTR(9); 368 HFI1_VL2MTU_ATTR(10); 369 HFI1_VL2MTU_ATTR(11); 370 HFI1_VL2MTU_ATTR(12); 371 HFI1_VL2MTU_ATTR(13); 372 HFI1_VL2MTU_ATTR(14); 373 HFI1_VL2MTU_ATTR(15); 374 375 static 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 395 static 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 */ 406 static 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 } 414 static DEVICE_ATTR_RO(hw_rev); 415 416 static 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 } 428 static DEVICE_ATTR_RO(board_id); 429 430 static 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 } 440 static DEVICE_ATTR_RO(boardversion); 441 442 static 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 } 459 static DEVICE_ATTR_RO(nctxts); 460 461 static 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 } 471 static DEVICE_ATTR_RO(nfreectxts); 472 473 static 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 } 483 static DEVICE_ATTR_RO(serial); 484 485 static 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); 500 bail: 501 return ret < 0 ? ret : count; 502 } 503 static 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 */ 515 static 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 } 537 static 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 */ 545 static 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 557 const struct attribute_group ib_hfi1_attr_group = { 558 .attrs = hfi1_attributes, 559 }; 560 561 const 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 569 struct 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 575 static 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 588 static 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 605 static const struct sysfs_ops sde_sysfs_ops = { 606 .show = sde_show, 607 .store = sde_store, 608 }; 609 610 static 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 618 static 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 623 static 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 629 static 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 640 static SDE_ATTR(cpu_list, S_IWUSR | S_IRUGO, 641 sde_show_cpu_to_sde_map, 642 sde_store_cpu_to_sde_map); 643 static SDE_ATTR(vl, S_IRUGO, sde_show_vl, NULL); 644 645 static 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 */ 653 int 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; 675 bail: 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 */ 690 void 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 } 698