Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2012 Intel Corporation.  All rights reserved.
0003  * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
0004  * Copyright (c) 2006 PathScale, Inc. All rights reserved.
0005  *
0006  * This software is available to you under a choice of one of two
0007  * licenses.  You may choose to be licensed under the terms of the GNU
0008  * General Public License (GPL) Version 2, available from the file
0009  * COPYING in the main directory of this source tree, or the
0010  * OpenIB.org BSD license below:
0011  *
0012  *     Redistribution and use in source and binary forms, with or
0013  *     without modification, are permitted provided that the following
0014  *     conditions are met:
0015  *
0016  *      - Redistributions of source code must retain the above
0017  *        copyright notice, this list of conditions and the following
0018  *        disclaimer.
0019  *
0020  *      - Redistributions in binary form must reproduce the above
0021  *        copyright notice, this list of conditions and the following
0022  *        disclaimer in the documentation and/or other materials
0023  *        provided with the distribution.
0024  *
0025  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0026  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0027  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0028  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
0029  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0030  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0031  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0032  * SOFTWARE.
0033  */
0034 #include <linux/ctype.h>
0035 #include <rdma/ib_sysfs.h>
0036 
0037 #include "qib.h"
0038 #include "qib_mad.h"
0039 
0040 static struct qib_pportdata *qib_get_pportdata_kobj(struct kobject *kobj)
0041 {
0042     u32 port_num;
0043     struct ib_device *ibdev = ib_port_sysfs_get_ibdev_kobj(kobj, &port_num);
0044     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0045 
0046     return &dd->pport[port_num - 1];
0047 }
0048 
0049 /*
0050  * Get/Set heartbeat enable. OR of 1=enabled, 2=auto
0051  */
0052 static ssize_t hrtbt_enable_show(struct ib_device *ibdev, u32 port_num,
0053                  struct ib_port_attribute *attr, char *buf)
0054 {
0055     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0056     struct qib_pportdata *ppd = &dd->pport[port_num - 1];
0057 
0058     return sysfs_emit(buf, "%d\n", dd->f_get_ib_cfg(ppd, QIB_IB_CFG_HRTBT));
0059 }
0060 
0061 static ssize_t hrtbt_enable_store(struct ib_device *ibdev, u32 port_num,
0062                   struct ib_port_attribute *attr,
0063                   const char *buf, size_t count)
0064 {
0065     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0066     struct qib_pportdata *ppd = &dd->pport[port_num - 1];
0067     int ret;
0068     u16 val;
0069 
0070     ret = kstrtou16(buf, 0, &val);
0071     if (ret) {
0072         qib_dev_err(dd, "attempt to set invalid Heartbeat enable\n");
0073         return ret;
0074     }
0075 
0076     /*
0077      * Set the "intentional" heartbeat enable per either of
0078      * "Enable" and "Auto", as these are normally set together.
0079      * This bit is consulted when leaving loopback mode,
0080      * because entering loopback mode overrides it and automatically
0081      * disables heartbeat.
0082      */
0083     ret = dd->f_set_ib_cfg(ppd, QIB_IB_CFG_HRTBT, val);
0084     return ret < 0 ? ret : count;
0085 }
0086 static IB_PORT_ATTR_RW(hrtbt_enable);
0087 
0088 static ssize_t loopback_store(struct ib_device *ibdev, u32 port_num,
0089                   struct ib_port_attribute *attr, const char *buf,
0090                   size_t count)
0091 {
0092     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0093     struct qib_pportdata *ppd = &dd->pport[port_num - 1];
0094     int ret = count, r;
0095 
0096     r = dd->f_set_ib_loopback(ppd, buf);
0097     if (r < 0)
0098         ret = r;
0099 
0100     return ret;
0101 }
0102 static IB_PORT_ATTR_WO(loopback);
0103 
0104 static ssize_t led_override_store(struct ib_device *ibdev, u32 port_num,
0105                   struct ib_port_attribute *attr,
0106                   const char *buf, size_t count)
0107 {
0108     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0109     struct qib_pportdata *ppd = &dd->pport[port_num - 1];
0110     int ret;
0111     u16 val;
0112 
0113     ret = kstrtou16(buf, 0, &val);
0114     if (ret) {
0115         qib_dev_err(dd, "attempt to set invalid LED override\n");
0116         return ret;
0117     }
0118 
0119     qib_set_led_override(ppd, val);
0120     return count;
0121 }
0122 static IB_PORT_ATTR_WO(led_override);
0123 
0124 static ssize_t status_show(struct ib_device *ibdev, u32 port_num,
0125                struct ib_port_attribute *attr, char *buf)
0126 {
0127     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0128     struct qib_pportdata *ppd = &dd->pport[port_num - 1];
0129 
0130     if (!ppd->statusp)
0131         return -EINVAL;
0132 
0133     return sysfs_emit(buf, "0x%llx\n", (unsigned long long)*(ppd->statusp));
0134 }
0135 static IB_PORT_ATTR_RO(status);
0136 
0137 /*
0138  * For userland compatibility, these offsets must remain fixed.
0139  * They are strings for QIB_STATUS_*
0140  */
0141 static const char * const qib_status_str[] = {
0142     "Initted",
0143     "",
0144     "",
0145     "",
0146     "",
0147     "Present",
0148     "IB_link_up",
0149     "IB_configured",
0150     "",
0151     "Fatal_Hardware_Error",
0152     NULL,
0153 };
0154 
0155 static ssize_t status_str_show(struct ib_device *ibdev, u32 port_num,
0156                    struct ib_port_attribute *attr, char *buf)
0157 {
0158     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0159     struct qib_pportdata *ppd = &dd->pport[port_num - 1];
0160     int i, any;
0161     u64 s;
0162     ssize_t ret;
0163 
0164     if (!ppd->statusp) {
0165         ret = -EINVAL;
0166         goto bail;
0167     }
0168 
0169     s = *(ppd->statusp);
0170     *buf = '\0';
0171     for (any = i = 0; s && qib_status_str[i]; i++) {
0172         if (s & 1) {
0173             /* if overflow */
0174             if (any && strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)
0175                 break;
0176             if (strlcat(buf, qib_status_str[i], PAGE_SIZE) >=
0177                     PAGE_SIZE)
0178                 break;
0179             any = 1;
0180         }
0181         s >>= 1;
0182     }
0183     if (any)
0184         strlcat(buf, "\n", PAGE_SIZE);
0185 
0186     ret = strlen(buf);
0187 
0188 bail:
0189     return ret;
0190 }
0191 static IB_PORT_ATTR_RO(status_str);
0192 
0193 /* end of per-port functions */
0194 
0195 static struct attribute *port_linkcontrol_attributes[] = {
0196     &ib_port_attr_loopback.attr,
0197     &ib_port_attr_led_override.attr,
0198     &ib_port_attr_hrtbt_enable.attr,
0199     &ib_port_attr_status.attr,
0200     &ib_port_attr_status_str.attr,
0201     NULL
0202 };
0203 
0204 static const struct attribute_group port_linkcontrol_group = {
0205     .name = "linkcontrol",
0206     .attrs = port_linkcontrol_attributes,
0207 };
0208 
0209 /*
0210  * Start of per-port congestion control structures and support code
0211  */
0212 
0213 /*
0214  * Congestion control table size followed by table entries
0215  */
0216 static ssize_t cc_table_bin_read(struct file *filp, struct kobject *kobj,
0217                  struct bin_attribute *bin_attr, char *buf,
0218                  loff_t pos, size_t count)
0219 {
0220     struct qib_pportdata *ppd = qib_get_pportdata_kobj(kobj);
0221     int ret;
0222 
0223     if (!qib_cc_table_size || !ppd->ccti_entries_shadow)
0224         return -EINVAL;
0225 
0226     ret = ppd->total_cct_entry * sizeof(struct ib_cc_table_entry_shadow)
0227          + sizeof(__be16);
0228 
0229     if (pos > ret)
0230         return -EINVAL;
0231 
0232     if (count > ret - pos)
0233         count = ret - pos;
0234 
0235     if (!count)
0236         return count;
0237 
0238     spin_lock(&ppd->cc_shadow_lock);
0239     memcpy(buf, ppd->ccti_entries_shadow, count);
0240     spin_unlock(&ppd->cc_shadow_lock);
0241 
0242     return count;
0243 }
0244 static BIN_ATTR_RO(cc_table_bin, PAGE_SIZE);
0245 
0246 /*
0247  * Congestion settings: port control, control map and an array of 16
0248  * entries for the congestion entries - increase, timer, event log
0249  * trigger threshold and the minimum injection rate delay.
0250  */
0251 static ssize_t cc_setting_bin_read(struct file *filp, struct kobject *kobj,
0252                    struct bin_attribute *bin_attr, char *buf,
0253                    loff_t pos, size_t count)
0254 {
0255     struct qib_pportdata *ppd = qib_get_pportdata_kobj(kobj);
0256     int ret;
0257 
0258     if (!qib_cc_table_size || !ppd->congestion_entries_shadow)
0259         return -EINVAL;
0260 
0261     ret = sizeof(struct ib_cc_congestion_setting_attr_shadow);
0262 
0263     if (pos > ret)
0264         return -EINVAL;
0265     if (count > ret - pos)
0266         count = ret - pos;
0267 
0268     if (!count)
0269         return count;
0270 
0271     spin_lock(&ppd->cc_shadow_lock);
0272     memcpy(buf, ppd->congestion_entries_shadow, count);
0273     spin_unlock(&ppd->cc_shadow_lock);
0274 
0275     return count;
0276 }
0277 static BIN_ATTR_RO(cc_setting_bin, PAGE_SIZE);
0278 
0279 static struct bin_attribute *port_ccmgta_attributes[] = {
0280     &bin_attr_cc_setting_bin,
0281     &bin_attr_cc_table_bin,
0282     NULL,
0283 };
0284 
0285 static umode_t qib_ccmgta_is_bin_visible(struct kobject *kobj,
0286                  struct bin_attribute *attr, int n)
0287 {
0288     struct qib_pportdata *ppd = qib_get_pportdata_kobj(kobj);
0289 
0290     if (!qib_cc_table_size || !ppd->congestion_entries_shadow)
0291         return 0;
0292     return attr->attr.mode;
0293 }
0294 
0295 static const struct attribute_group port_ccmgta_attribute_group = {
0296     .name = "CCMgtA",
0297     .is_bin_visible = qib_ccmgta_is_bin_visible,
0298     .bin_attrs = port_ccmgta_attributes,
0299 };
0300 
0301 /* Start sl2vl */
0302 
0303 struct qib_sl2vl_attr {
0304     struct ib_port_attribute attr;
0305     int sl;
0306 };
0307 
0308 static ssize_t sl2vl_attr_show(struct ib_device *ibdev, u32 port_num,
0309                    struct ib_port_attribute *attr, char *buf)
0310 {
0311     struct qib_sl2vl_attr *sattr =
0312         container_of(attr, struct qib_sl2vl_attr, attr);
0313     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0314     struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;
0315 
0316     return sysfs_emit(buf, "%u\n", qibp->sl_to_vl[sattr->sl]);
0317 }
0318 
0319 #define QIB_SL2VL_ATTR(N)                                                      \
0320     static struct qib_sl2vl_attr qib_sl2vl_attr_##N = {                    \
0321         .attr = __ATTR(N, 0444, sl2vl_attr_show, NULL),                \
0322         .sl = N,                                                       \
0323     }
0324 
0325 QIB_SL2VL_ATTR(0);
0326 QIB_SL2VL_ATTR(1);
0327 QIB_SL2VL_ATTR(2);
0328 QIB_SL2VL_ATTR(3);
0329 QIB_SL2VL_ATTR(4);
0330 QIB_SL2VL_ATTR(5);
0331 QIB_SL2VL_ATTR(6);
0332 QIB_SL2VL_ATTR(7);
0333 QIB_SL2VL_ATTR(8);
0334 QIB_SL2VL_ATTR(9);
0335 QIB_SL2VL_ATTR(10);
0336 QIB_SL2VL_ATTR(11);
0337 QIB_SL2VL_ATTR(12);
0338 QIB_SL2VL_ATTR(13);
0339 QIB_SL2VL_ATTR(14);
0340 QIB_SL2VL_ATTR(15);
0341 
0342 static struct attribute *port_sl2vl_attributes[] = {
0343     &qib_sl2vl_attr_0.attr.attr,
0344     &qib_sl2vl_attr_1.attr.attr,
0345     &qib_sl2vl_attr_2.attr.attr,
0346     &qib_sl2vl_attr_3.attr.attr,
0347     &qib_sl2vl_attr_4.attr.attr,
0348     &qib_sl2vl_attr_5.attr.attr,
0349     &qib_sl2vl_attr_6.attr.attr,
0350     &qib_sl2vl_attr_7.attr.attr,
0351     &qib_sl2vl_attr_8.attr.attr,
0352     &qib_sl2vl_attr_9.attr.attr,
0353     &qib_sl2vl_attr_10.attr.attr,
0354     &qib_sl2vl_attr_11.attr.attr,
0355     &qib_sl2vl_attr_12.attr.attr,
0356     &qib_sl2vl_attr_13.attr.attr,
0357     &qib_sl2vl_attr_14.attr.attr,
0358     &qib_sl2vl_attr_15.attr.attr,
0359     NULL
0360 };
0361 
0362 static const struct attribute_group port_sl2vl_group = {
0363     .name = "sl2vl",
0364     .attrs = port_sl2vl_attributes,
0365 };
0366 
0367 /* End sl2vl */
0368 
0369 /* Start diag_counters */
0370 
0371 struct qib_diagc_attr {
0372     struct ib_port_attribute attr;
0373     size_t counter;
0374 };
0375 
0376 static ssize_t diagc_attr_show(struct ib_device *ibdev, u32 port_num,
0377                    struct ib_port_attribute *attr, char *buf)
0378 {
0379     struct qib_diagc_attr *dattr =
0380         container_of(attr, struct qib_diagc_attr, attr);
0381     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0382     struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;
0383 
0384     return sysfs_emit(buf, "%llu\n", *((u64 *)qibp + dattr->counter));
0385 }
0386 
0387 static ssize_t diagc_attr_store(struct ib_device *ibdev, u32 port_num,
0388                 struct ib_port_attribute *attr, const char *buf,
0389                 size_t count)
0390 {
0391     struct qib_diagc_attr *dattr =
0392         container_of(attr, struct qib_diagc_attr, attr);
0393     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0394     struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;
0395     u64 val;
0396     int ret;
0397 
0398     ret = kstrtou64(buf, 0, &val);
0399     if (ret)
0400         return ret;
0401     *((u64 *)qibp + dattr->counter) = val;
0402     return count;
0403 }
0404 
0405 #define QIB_DIAGC_ATTR(N)                                                      \
0406     static_assert(__same_type(((struct qib_ibport *)0)->rvp.n_##N, u64));  \
0407     static struct qib_diagc_attr qib_diagc_attr_##N = {                    \
0408         .attr = __ATTR(N, 0664, diagc_attr_show, diagc_attr_store),    \
0409         .counter =                                                     \
0410             offsetof(struct qib_ibport, rvp.n_##N) / sizeof(u64)   \
0411     }
0412 
0413 QIB_DIAGC_ATTR(rc_resends);
0414 QIB_DIAGC_ATTR(seq_naks);
0415 QIB_DIAGC_ATTR(rdma_seq);
0416 QIB_DIAGC_ATTR(rnr_naks);
0417 QIB_DIAGC_ATTR(other_naks);
0418 QIB_DIAGC_ATTR(rc_timeouts);
0419 QIB_DIAGC_ATTR(loop_pkts);
0420 QIB_DIAGC_ATTR(pkt_drops);
0421 QIB_DIAGC_ATTR(dmawait);
0422 QIB_DIAGC_ATTR(unaligned);
0423 QIB_DIAGC_ATTR(rc_dupreq);
0424 QIB_DIAGC_ATTR(rc_seqnak);
0425 QIB_DIAGC_ATTR(rc_crwaits);
0426 
0427 static u64 get_all_cpu_total(u64 __percpu *cntr)
0428 {
0429     int cpu;
0430     u64 counter = 0;
0431 
0432     for_each_possible_cpu(cpu)
0433         counter += *per_cpu_ptr(cntr, cpu);
0434     return counter;
0435 }
0436 
0437 static ssize_t qib_store_per_cpu(struct qib_devdata *dd, const char *buf,
0438                  size_t count, u64 *zero, u64 cur)
0439 {
0440     u32 val;
0441     int ret;
0442 
0443     ret = kstrtou32(buf, 0, &val);
0444     if (ret)
0445         return ret;
0446     if (val != 0) {
0447         qib_dev_err(dd, "Per CPU cntrs can only be zeroed");
0448         return count;
0449     }
0450     *zero = cur;
0451     return count;
0452 }
0453 
0454 static ssize_t rc_acks_show(struct ib_device *ibdev, u32 port_num,
0455                 struct ib_port_attribute *attr, char *buf)
0456 {
0457     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0458     struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;
0459 
0460     return sysfs_emit(buf, "%llu\n",
0461               get_all_cpu_total(qibp->rvp.rc_acks) -
0462                   qibp->rvp.z_rc_acks);
0463 }
0464 
0465 static ssize_t rc_acks_store(struct ib_device *ibdev, u32 port_num,
0466                  struct ib_port_attribute *attr, const char *buf,
0467                  size_t count)
0468 {
0469     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0470     struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;
0471 
0472     return qib_store_per_cpu(dd, buf, count, &qibp->rvp.z_rc_acks,
0473                  get_all_cpu_total(qibp->rvp.rc_acks));
0474 }
0475 static IB_PORT_ATTR_RW(rc_acks);
0476 
0477 static ssize_t rc_qacks_show(struct ib_device *ibdev, u32 port_num,
0478                  struct ib_port_attribute *attr, char *buf)
0479 {
0480     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0481     struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;
0482 
0483     return sysfs_emit(buf, "%llu\n",
0484               get_all_cpu_total(qibp->rvp.rc_qacks) -
0485                   qibp->rvp.z_rc_qacks);
0486 }
0487 
0488 static ssize_t rc_qacks_store(struct ib_device *ibdev, u32 port_num,
0489                   struct ib_port_attribute *attr, const char *buf,
0490                   size_t count)
0491 {
0492     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0493     struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;
0494 
0495     return qib_store_per_cpu(dd, buf, count, &qibp->rvp.z_rc_qacks,
0496                  get_all_cpu_total(qibp->rvp.rc_qacks));
0497 }
0498 static IB_PORT_ATTR_RW(rc_qacks);
0499 
0500 static ssize_t rc_delayed_comp_show(struct ib_device *ibdev, u32 port_num,
0501                     struct ib_port_attribute *attr, char *buf)
0502 {
0503     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0504     struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;
0505 
0506     return sysfs_emit(buf, "%llu\n",
0507              get_all_cpu_total(qibp->rvp.rc_delayed_comp) -
0508                  qibp->rvp.z_rc_delayed_comp);
0509 }
0510 
0511 static ssize_t rc_delayed_comp_store(struct ib_device *ibdev, u32 port_num,
0512                      struct ib_port_attribute *attr,
0513                      const char *buf, size_t count)
0514 {
0515     struct qib_devdata *dd = dd_from_ibdev(ibdev);
0516     struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;
0517 
0518     return qib_store_per_cpu(dd, buf, count, &qibp->rvp.z_rc_delayed_comp,
0519                  get_all_cpu_total(qibp->rvp.rc_delayed_comp));
0520 }
0521 static IB_PORT_ATTR_RW(rc_delayed_comp);
0522 
0523 static struct attribute *port_diagc_attributes[] = {
0524     &qib_diagc_attr_rc_resends.attr.attr,
0525     &qib_diagc_attr_seq_naks.attr.attr,
0526     &qib_diagc_attr_rdma_seq.attr.attr,
0527     &qib_diagc_attr_rnr_naks.attr.attr,
0528     &qib_diagc_attr_other_naks.attr.attr,
0529     &qib_diagc_attr_rc_timeouts.attr.attr,
0530     &qib_diagc_attr_loop_pkts.attr.attr,
0531     &qib_diagc_attr_pkt_drops.attr.attr,
0532     &qib_diagc_attr_dmawait.attr.attr,
0533     &qib_diagc_attr_unaligned.attr.attr,
0534     &qib_diagc_attr_rc_dupreq.attr.attr,
0535     &qib_diagc_attr_rc_seqnak.attr.attr,
0536     &qib_diagc_attr_rc_crwaits.attr.attr,
0537     &ib_port_attr_rc_acks.attr,
0538     &ib_port_attr_rc_qacks.attr,
0539     &ib_port_attr_rc_delayed_comp.attr,
0540     NULL
0541 };
0542 
0543 static const struct attribute_group port_diagc_group = {
0544     .name = "diag_counters",
0545     .attrs = port_diagc_attributes,
0546 };
0547 
0548 /* End diag_counters */
0549 
0550 const struct attribute_group *qib_attr_port_groups[] = {
0551     &port_linkcontrol_group,
0552     &port_ccmgta_attribute_group,
0553     &port_sl2vl_group,
0554     &port_diagc_group,
0555     NULL,
0556 };
0557 
0558 /* end of per-port file structures and support code */
0559 
0560 /*
0561  * Start of per-unit (or driver, in some cases, but replicated
0562  * per unit) functions (these get a device *)
0563  */
0564 static ssize_t hw_rev_show(struct device *device, struct device_attribute *attr,
0565                char *buf)
0566 {
0567     struct qib_ibdev *dev =
0568         rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);
0569 
0570     return sysfs_emit(buf, "%x\n", dd_from_dev(dev)->minrev);
0571 }
0572 static DEVICE_ATTR_RO(hw_rev);
0573 
0574 static ssize_t hca_type_show(struct device *device,
0575                  struct device_attribute *attr, char *buf)
0576 {
0577     struct qib_ibdev *dev =
0578         rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);
0579     struct qib_devdata *dd = dd_from_dev(dev);
0580 
0581     if (!dd->boardname)
0582         return -EINVAL;
0583     return sysfs_emit(buf, "%s\n", dd->boardname);
0584 }
0585 static DEVICE_ATTR_RO(hca_type);
0586 static DEVICE_ATTR(board_id, 0444, hca_type_show, NULL);
0587 
0588 static ssize_t version_show(struct device *device,
0589                 struct device_attribute *attr, char *buf)
0590 {
0591     /* The string printed here is already newline-terminated. */
0592     return sysfs_emit(buf, "%s", (char *)ib_qib_version);
0593 }
0594 static DEVICE_ATTR_RO(version);
0595 
0596 static ssize_t boardversion_show(struct device *device,
0597                  struct device_attribute *attr, char *buf)
0598 {
0599     struct qib_ibdev *dev =
0600         rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);
0601     struct qib_devdata *dd = dd_from_dev(dev);
0602 
0603     /* The string printed here is already newline-terminated. */
0604     return sysfs_emit(buf, "%s", dd->boardversion);
0605 }
0606 static DEVICE_ATTR_RO(boardversion);
0607 
0608 static ssize_t localbus_info_show(struct device *device,
0609                   struct device_attribute *attr, char *buf)
0610 {
0611     struct qib_ibdev *dev =
0612         rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);
0613     struct qib_devdata *dd = dd_from_dev(dev);
0614 
0615     /* The string printed here is already newline-terminated. */
0616     return sysfs_emit(buf, "%s", dd->lbus_info);
0617 }
0618 static DEVICE_ATTR_RO(localbus_info);
0619 
0620 static ssize_t nctxts_show(struct device *device,
0621                struct device_attribute *attr, char *buf)
0622 {
0623     struct qib_ibdev *dev =
0624         rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);
0625     struct qib_devdata *dd = dd_from_dev(dev);
0626 
0627     /* Return the number of user ports (contexts) available. */
0628     /* The calculation below deals with a special case where
0629      * cfgctxts is set to 1 on a single-port board. */
0630     return sysfs_emit(buf, "%u\n",
0631               (dd->first_user_ctxt > dd->cfgctxts) ?
0632                   0 :
0633                   (dd->cfgctxts - dd->first_user_ctxt));
0634 }
0635 static DEVICE_ATTR_RO(nctxts);
0636 
0637 static ssize_t nfreectxts_show(struct device *device,
0638                    struct device_attribute *attr, char *buf)
0639 {
0640     struct qib_ibdev *dev =
0641         rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);
0642     struct qib_devdata *dd = dd_from_dev(dev);
0643 
0644     /* Return the number of free user ports (contexts) available. */
0645     return sysfs_emit(buf, "%u\n", dd->freectxts);
0646 }
0647 static DEVICE_ATTR_RO(nfreectxts);
0648 
0649 static ssize_t serial_show(struct device *device, struct device_attribute *attr,
0650                char *buf)
0651 {
0652     struct qib_ibdev *dev =
0653         rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);
0654     struct qib_devdata *dd = dd_from_dev(dev);
0655     const u8 *end = memchr(dd->serial, 0, ARRAY_SIZE(dd->serial));
0656     int size = end ? end - dd->serial : ARRAY_SIZE(dd->serial);
0657 
0658     return sysfs_emit(buf, ".%*s\n", size, dd->serial);
0659 }
0660 static DEVICE_ATTR_RO(serial);
0661 
0662 static ssize_t chip_reset_store(struct device *device,
0663                 struct device_attribute *attr, const char *buf,
0664                 size_t count)
0665 {
0666     struct qib_ibdev *dev =
0667         rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);
0668     struct qib_devdata *dd = dd_from_dev(dev);
0669     int ret;
0670 
0671     if (count < 5 || memcmp(buf, "reset", 5) || !dd->diag_client) {
0672         ret = -EINVAL;
0673         goto bail;
0674     }
0675 
0676     ret = qib_reset_device(dd->unit);
0677 bail:
0678     return ret < 0 ? ret : count;
0679 }
0680 static DEVICE_ATTR_WO(chip_reset);
0681 
0682 /*
0683  * Dump tempsense regs. in decimal, to ease shell-scripts.
0684  */
0685 static ssize_t tempsense_show(struct device *device,
0686                   struct device_attribute *attr, char *buf)
0687 {
0688     struct qib_ibdev *dev =
0689         rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);
0690     struct qib_devdata *dd = dd_from_dev(dev);
0691     int i;
0692     u8 regvals[8];
0693 
0694     for (i = 0; i < 8; i++) {
0695         int ret;
0696 
0697         if (i == 6)
0698             continue;
0699         ret = dd->f_tempsense_rd(dd, i);
0700         if (ret < 0)
0701             return ret; /* return error on bad read */
0702         regvals[i] = ret;
0703     }
0704     return sysfs_emit(buf, "%d %d %02X %02X %d %d\n",
0705               (signed char)regvals[0],
0706               (signed char)regvals[1],
0707               regvals[2],
0708               regvals[3],
0709               (signed char)regvals[5],
0710               (signed char)regvals[7]);
0711 }
0712 static DEVICE_ATTR_RO(tempsense);
0713 
0714 /*
0715  * end of per-unit (or driver, in some cases, but replicated
0716  * per unit) functions
0717  */
0718 
0719 /* start of per-unit file structures and support code */
0720 static struct attribute *qib_attributes[] = {
0721     &dev_attr_hw_rev.attr,
0722     &dev_attr_hca_type.attr,
0723     &dev_attr_board_id.attr,
0724     &dev_attr_version.attr,
0725     &dev_attr_nctxts.attr,
0726     &dev_attr_nfreectxts.attr,
0727     &dev_attr_serial.attr,
0728     &dev_attr_boardversion.attr,
0729     &dev_attr_tempsense.attr,
0730     &dev_attr_localbus_info.attr,
0731     &dev_attr_chip_reset.attr,
0732     NULL,
0733 };
0734 
0735 const struct attribute_group qib_attr_group = {
0736     .attrs = qib_attributes,
0737 };