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