sysfs.c 18 KB

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