brintos

brintos / linux-shallow public Read only

0
0
Text · 19.7 KiB · 53ec751 Raw
732 lines · c
1/*2 * Copyright (c) 2012 Intel Corporation.  All rights reserved.3 * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.4 * Copyright (c) 2006 PathScale, Inc. All rights reserved.5 *6 * This software is available to you under a choice of one of two7 * licenses.  You may choose to be licensed under the terms of the GNU8 * General Public License (GPL) Version 2, available from the file9 * COPYING in the main directory of this source tree, or the10 * OpenIB.org BSD license below:11 *12 *     Redistribution and use in source and binary forms, with or13 *     without modification, are permitted provided that the following14 *     conditions are met:15 *16 *      - Redistributions of source code must retain the above17 *        copyright notice, this list of conditions and the following18 *        disclaimer.19 *20 *      - Redistributions in binary form must reproduce the above21 *        copyright notice, this list of conditions and the following22 *        disclaimer in the documentation and/or other materials23 *        provided with the distribution.24 *25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE32 * SOFTWARE.33 */34#include <linux/ctype.h>35#include <rdma/ib_sysfs.h>36 37#include "qib.h"38#include "qib_mad.h"39 40static struct qib_pportdata *qib_get_pportdata_kobj(struct kobject *kobj)41{42	u32 port_num;43	struct ib_device *ibdev = ib_port_sysfs_get_ibdev_kobj(kobj, &port_num);44	struct qib_devdata *dd = dd_from_ibdev(ibdev);45 46	return &dd->pport[port_num - 1];47}48 49/*50 * Get/Set heartbeat enable. OR of 1=enabled, 2=auto51 */52static ssize_t hrtbt_enable_show(struct ib_device *ibdev, u32 port_num,53				 struct ib_port_attribute *attr, char *buf)54{55	struct qib_devdata *dd = dd_from_ibdev(ibdev);56	struct qib_pportdata *ppd = &dd->pport[port_num - 1];57 58	return sysfs_emit(buf, "%d\n", dd->f_get_ib_cfg(ppd, QIB_IB_CFG_HRTBT));59}60 61static ssize_t hrtbt_enable_store(struct ib_device *ibdev, u32 port_num,62				  struct ib_port_attribute *attr,63				  const char *buf, size_t count)64{65	struct qib_devdata *dd = dd_from_ibdev(ibdev);66	struct qib_pportdata *ppd = &dd->pport[port_num - 1];67	int ret;68	u16 val;69 70	ret = kstrtou16(buf, 0, &val);71	if (ret) {72		qib_dev_err(dd, "attempt to set invalid Heartbeat enable\n");73		return ret;74	}75 76	/*77	 * Set the "intentional" heartbeat enable per either of78	 * "Enable" and "Auto", as these are normally set together.79	 * This bit is consulted when leaving loopback mode,80	 * because entering loopback mode overrides it and automatically81	 * disables heartbeat.82	 */83	ret = dd->f_set_ib_cfg(ppd, QIB_IB_CFG_HRTBT, val);84	return ret < 0 ? ret : count;85}86static IB_PORT_ATTR_RW(hrtbt_enable);87 88static ssize_t loopback_store(struct ib_device *ibdev, u32 port_num,89			      struct ib_port_attribute *attr, const char *buf,90			      size_t count)91{92	struct qib_devdata *dd = dd_from_ibdev(ibdev);93	struct qib_pportdata *ppd = &dd->pport[port_num - 1];94	int ret = count, r;95 96	r = dd->f_set_ib_loopback(ppd, buf);97	if (r < 0)98		ret = r;99 100	return ret;101}102static IB_PORT_ATTR_WO(loopback);103 104static ssize_t led_override_store(struct ib_device *ibdev, u32 port_num,105				  struct ib_port_attribute *attr,106				  const char *buf, size_t count)107{108	struct qib_devdata *dd = dd_from_ibdev(ibdev);109	struct qib_pportdata *ppd = &dd->pport[port_num - 1];110	int ret;111	u16 val;112 113	ret = kstrtou16(buf, 0, &val);114	if (ret) {115		qib_dev_err(dd, "attempt to set invalid LED override\n");116		return ret;117	}118 119	qib_set_led_override(ppd, val);120	return count;121}122static IB_PORT_ATTR_WO(led_override);123 124static ssize_t status_show(struct ib_device *ibdev, u32 port_num,125			   struct ib_port_attribute *attr, char *buf)126{127	struct qib_devdata *dd = dd_from_ibdev(ibdev);128	struct qib_pportdata *ppd = &dd->pport[port_num - 1];129 130	if (!ppd->statusp)131		return -EINVAL;132 133	return sysfs_emit(buf, "0x%llx\n", (unsigned long long)*(ppd->statusp));134}135static IB_PORT_ATTR_RO(status);136 137/*138 * For userland compatibility, these offsets must remain fixed.139 * They are strings for QIB_STATUS_*140 */141static const char * const qib_status_str[] = {142	"Initted",143	"",144	"",145	"",146	"",147	"Present",148	"IB_link_up",149	"IB_configured",150	"",151	"Fatal_Hardware_Error",152	NULL,153};154 155static ssize_t status_str_show(struct ib_device *ibdev, u32 port_num,156			       struct ib_port_attribute *attr, char *buf)157{158	struct qib_devdata *dd = dd_from_ibdev(ibdev);159	struct qib_pportdata *ppd = &dd->pport[port_num - 1];160	int i, any;161	u64 s;162	ssize_t ret;163 164	if (!ppd->statusp) {165		ret = -EINVAL;166		goto bail;167	}168 169	s = *(ppd->statusp);170	*buf = '\0';171	for (any = i = 0; s && qib_status_str[i]; i++) {172		if (s & 1) {173			/* if overflow */174			if (any && strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)175				break;176			if (strlcat(buf, qib_status_str[i], PAGE_SIZE) >=177					PAGE_SIZE)178				break;179			any = 1;180		}181		s >>= 1;182	}183	if (any)184		strlcat(buf, "\n", PAGE_SIZE);185 186	ret = strlen(buf);187 188bail:189	return ret;190}191static IB_PORT_ATTR_RO(status_str);192 193/* end of per-port functions */194 195static struct attribute *port_linkcontrol_attributes[] = {196	&ib_port_attr_loopback.attr,197	&ib_port_attr_led_override.attr,198	&ib_port_attr_hrtbt_enable.attr,199	&ib_port_attr_status.attr,200	&ib_port_attr_status_str.attr,201	NULL202};203 204static const struct attribute_group port_linkcontrol_group = {205	.name = "linkcontrol",206	.attrs = port_linkcontrol_attributes,207};208 209/*210 * Start of per-port congestion control structures and support code211 */212 213/*214 * Congestion control table size followed by table entries215 */216static ssize_t cc_table_bin_read(struct file *filp, struct kobject *kobj,217				 struct bin_attribute *bin_attr, char *buf,218				 loff_t pos, size_t count)219{220	struct qib_pportdata *ppd = qib_get_pportdata_kobj(kobj);221	int ret;222 223	if (!qib_cc_table_size || !ppd->ccti_entries_shadow)224		return -EINVAL;225 226	ret = ppd->total_cct_entry * sizeof(struct ib_cc_table_entry_shadow)227		 + sizeof(__be16);228 229	if (pos > ret)230		return -EINVAL;231 232	if (count > ret - pos)233		count = ret - pos;234 235	if (!count)236		return count;237 238	spin_lock(&ppd->cc_shadow_lock);239	memcpy(buf, ppd->ccti_entries_shadow, count);240	spin_unlock(&ppd->cc_shadow_lock);241 242	return count;243}244static BIN_ATTR_RO(cc_table_bin, PAGE_SIZE);245 246/*247 * Congestion settings: port control, control map and an array of 16248 * entries for the congestion entries - increase, timer, event log249 * trigger threshold and the minimum injection rate delay.250 */251static ssize_t cc_setting_bin_read(struct file *filp, struct kobject *kobj,252				   struct bin_attribute *bin_attr, char *buf,253				   loff_t pos, size_t count)254{255	struct qib_pportdata *ppd = qib_get_pportdata_kobj(kobj);256	int ret;257 258	if (!qib_cc_table_size || !ppd->congestion_entries_shadow)259		return -EINVAL;260 261	ret = sizeof(struct ib_cc_congestion_setting_attr_shadow);262 263	if (pos > ret)264		return -EINVAL;265	if (count > ret - pos)266		count = ret - pos;267 268	if (!count)269		return count;270 271	spin_lock(&ppd->cc_shadow_lock);272	memcpy(buf, ppd->congestion_entries_shadow, count);273	spin_unlock(&ppd->cc_shadow_lock);274 275	return count;276}277static BIN_ATTR_RO(cc_setting_bin, PAGE_SIZE);278 279static struct bin_attribute *port_ccmgta_attributes[] = {280	&bin_attr_cc_setting_bin,281	&bin_attr_cc_table_bin,282	NULL,283};284 285static umode_t qib_ccmgta_is_bin_visible(struct kobject *kobj,286				 struct bin_attribute *attr, int n)287{288	struct qib_pportdata *ppd = qib_get_pportdata_kobj(kobj);289 290	if (!qib_cc_table_size || !ppd->congestion_entries_shadow)291		return 0;292	return attr->attr.mode;293}294 295static const struct attribute_group port_ccmgta_attribute_group = {296	.name = "CCMgtA",297	.is_bin_visible = qib_ccmgta_is_bin_visible,298	.bin_attrs = port_ccmgta_attributes,299};300 301/* Start sl2vl */302 303struct qib_sl2vl_attr {304	struct ib_port_attribute attr;305	int sl;306};307 308static ssize_t sl2vl_attr_show(struct ib_device *ibdev, u32 port_num,309			       struct ib_port_attribute *attr, char *buf)310{311	struct qib_sl2vl_attr *sattr =312		container_of(attr, struct qib_sl2vl_attr, attr);313	struct qib_devdata *dd = dd_from_ibdev(ibdev);314	struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;315 316	return sysfs_emit(buf, "%u\n", qibp->sl_to_vl[sattr->sl]);317}318 319#define QIB_SL2VL_ATTR(N)                                                      \320	static struct qib_sl2vl_attr qib_sl2vl_attr_##N = {                    \321		.attr = __ATTR(N, 0444, sl2vl_attr_show, NULL),                \322		.sl = N,                                                       \323	}324 325QIB_SL2VL_ATTR(0);326QIB_SL2VL_ATTR(1);327QIB_SL2VL_ATTR(2);328QIB_SL2VL_ATTR(3);329QIB_SL2VL_ATTR(4);330QIB_SL2VL_ATTR(5);331QIB_SL2VL_ATTR(6);332QIB_SL2VL_ATTR(7);333QIB_SL2VL_ATTR(8);334QIB_SL2VL_ATTR(9);335QIB_SL2VL_ATTR(10);336QIB_SL2VL_ATTR(11);337QIB_SL2VL_ATTR(12);338QIB_SL2VL_ATTR(13);339QIB_SL2VL_ATTR(14);340QIB_SL2VL_ATTR(15);341 342static struct attribute *port_sl2vl_attributes[] = {343	&qib_sl2vl_attr_0.attr.attr,344	&qib_sl2vl_attr_1.attr.attr,345	&qib_sl2vl_attr_2.attr.attr,346	&qib_sl2vl_attr_3.attr.attr,347	&qib_sl2vl_attr_4.attr.attr,348	&qib_sl2vl_attr_5.attr.attr,349	&qib_sl2vl_attr_6.attr.attr,350	&qib_sl2vl_attr_7.attr.attr,351	&qib_sl2vl_attr_8.attr.attr,352	&qib_sl2vl_attr_9.attr.attr,353	&qib_sl2vl_attr_10.attr.attr,354	&qib_sl2vl_attr_11.attr.attr,355	&qib_sl2vl_attr_12.attr.attr,356	&qib_sl2vl_attr_13.attr.attr,357	&qib_sl2vl_attr_14.attr.attr,358	&qib_sl2vl_attr_15.attr.attr,359	NULL360};361 362static const struct attribute_group port_sl2vl_group = {363	.name = "sl2vl",364	.attrs = port_sl2vl_attributes,365};366 367/* End sl2vl */368 369/* Start diag_counters */370 371struct qib_diagc_attr {372	struct ib_port_attribute attr;373	size_t counter;374};375 376static ssize_t diagc_attr_show(struct ib_device *ibdev, u32 port_num,377			       struct ib_port_attribute *attr, char *buf)378{379	struct qib_diagc_attr *dattr =380		container_of(attr, struct qib_diagc_attr, attr);381	struct qib_devdata *dd = dd_from_ibdev(ibdev);382	struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;383 384	return sysfs_emit(buf, "%llu\n", *((u64 *)qibp + dattr->counter));385}386 387static ssize_t diagc_attr_store(struct ib_device *ibdev, u32 port_num,388				struct ib_port_attribute *attr, const char *buf,389				size_t count)390{391	struct qib_diagc_attr *dattr =392		container_of(attr, struct qib_diagc_attr, attr);393	struct qib_devdata *dd = dd_from_ibdev(ibdev);394	struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;395	u64 val;396	int ret;397 398	ret = kstrtou64(buf, 0, &val);399	if (ret)400		return ret;401	*((u64 *)qibp + dattr->counter) = val;402	return count;403}404 405#define QIB_DIAGC_ATTR(N)                                                      \406	static_assert(__same_type(((struct qib_ibport *)0)->rvp.n_##N, u64));  \407	static struct qib_diagc_attr qib_diagc_attr_##N = {                    \408		.attr = __ATTR(N, 0664, diagc_attr_show, diagc_attr_store),    \409		.counter =                                                     \410			offsetof(struct qib_ibport, rvp.n_##N) / sizeof(u64)   \411	}412 413QIB_DIAGC_ATTR(rc_resends);414QIB_DIAGC_ATTR(seq_naks);415QIB_DIAGC_ATTR(rdma_seq);416QIB_DIAGC_ATTR(rnr_naks);417QIB_DIAGC_ATTR(other_naks);418QIB_DIAGC_ATTR(rc_timeouts);419QIB_DIAGC_ATTR(loop_pkts);420QIB_DIAGC_ATTR(pkt_drops);421QIB_DIAGC_ATTR(dmawait);422QIB_DIAGC_ATTR(unaligned);423QIB_DIAGC_ATTR(rc_dupreq);424QIB_DIAGC_ATTR(rc_seqnak);425QIB_DIAGC_ATTR(rc_crwaits);426 427static u64 get_all_cpu_total(u64 __percpu *cntr)428{429	int cpu;430	u64 counter = 0;431 432	for_each_possible_cpu(cpu)433		counter += *per_cpu_ptr(cntr, cpu);434	return counter;435}436 437static ssize_t qib_store_per_cpu(struct qib_devdata *dd, const char *buf,438				 size_t count, u64 *zero, u64 cur)439{440	u32 val;441	int ret;442 443	ret = kstrtou32(buf, 0, &val);444	if (ret)445		return ret;446	if (val != 0) {447		qib_dev_err(dd, "Per CPU cntrs can only be zeroed");448		return count;449	}450	*zero = cur;451	return count;452}453 454static ssize_t rc_acks_show(struct ib_device *ibdev, u32 port_num,455			    struct ib_port_attribute *attr, char *buf)456{457	struct qib_devdata *dd = dd_from_ibdev(ibdev);458	struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;459 460	return sysfs_emit(buf, "%llu\n",461			  get_all_cpu_total(qibp->rvp.rc_acks) -462				  qibp->rvp.z_rc_acks);463}464 465static ssize_t rc_acks_store(struct ib_device *ibdev, u32 port_num,466			     struct ib_port_attribute *attr, const char *buf,467			     size_t count)468{469	struct qib_devdata *dd = dd_from_ibdev(ibdev);470	struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;471 472	return qib_store_per_cpu(dd, buf, count, &qibp->rvp.z_rc_acks,473				 get_all_cpu_total(qibp->rvp.rc_acks));474}475static IB_PORT_ATTR_RW(rc_acks);476 477static ssize_t rc_qacks_show(struct ib_device *ibdev, u32 port_num,478			     struct ib_port_attribute *attr, char *buf)479{480	struct qib_devdata *dd = dd_from_ibdev(ibdev);481	struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;482 483	return sysfs_emit(buf, "%llu\n",484			  get_all_cpu_total(qibp->rvp.rc_qacks) -485				  qibp->rvp.z_rc_qacks);486}487 488static ssize_t rc_qacks_store(struct ib_device *ibdev, u32 port_num,489			      struct ib_port_attribute *attr, const char *buf,490			      size_t count)491{492	struct qib_devdata *dd = dd_from_ibdev(ibdev);493	struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;494 495	return qib_store_per_cpu(dd, buf, count, &qibp->rvp.z_rc_qacks,496				 get_all_cpu_total(qibp->rvp.rc_qacks));497}498static IB_PORT_ATTR_RW(rc_qacks);499 500static ssize_t rc_delayed_comp_show(struct ib_device *ibdev, u32 port_num,501				    struct ib_port_attribute *attr, char *buf)502{503	struct qib_devdata *dd = dd_from_ibdev(ibdev);504	struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;505 506	return sysfs_emit(buf, "%llu\n",507			 get_all_cpu_total(qibp->rvp.rc_delayed_comp) -508				 qibp->rvp.z_rc_delayed_comp);509}510 511static ssize_t rc_delayed_comp_store(struct ib_device *ibdev, u32 port_num,512				     struct ib_port_attribute *attr,513				     const char *buf, size_t count)514{515	struct qib_devdata *dd = dd_from_ibdev(ibdev);516	struct qib_ibport *qibp = &dd->pport[port_num - 1].ibport_data;517 518	return qib_store_per_cpu(dd, buf, count, &qibp->rvp.z_rc_delayed_comp,519				 get_all_cpu_total(qibp->rvp.rc_delayed_comp));520}521static IB_PORT_ATTR_RW(rc_delayed_comp);522 523static struct attribute *port_diagc_attributes[] = {524	&qib_diagc_attr_rc_resends.attr.attr,525	&qib_diagc_attr_seq_naks.attr.attr,526	&qib_diagc_attr_rdma_seq.attr.attr,527	&qib_diagc_attr_rnr_naks.attr.attr,528	&qib_diagc_attr_other_naks.attr.attr,529	&qib_diagc_attr_rc_timeouts.attr.attr,530	&qib_diagc_attr_loop_pkts.attr.attr,531	&qib_diagc_attr_pkt_drops.attr.attr,532	&qib_diagc_attr_dmawait.attr.attr,533	&qib_diagc_attr_unaligned.attr.attr,534	&qib_diagc_attr_rc_dupreq.attr.attr,535	&qib_diagc_attr_rc_seqnak.attr.attr,536	&qib_diagc_attr_rc_crwaits.attr.attr,537	&ib_port_attr_rc_acks.attr,538	&ib_port_attr_rc_qacks.attr,539	&ib_port_attr_rc_delayed_comp.attr,540	NULL541};542 543static const struct attribute_group port_diagc_group = {544	.name = "diag_counters",545	.attrs = port_diagc_attributes,546};547 548/* End diag_counters */549 550const struct attribute_group *qib_attr_port_groups[] = {551	&port_linkcontrol_group,552	&port_ccmgta_attribute_group,553	&port_sl2vl_group,554	&port_diagc_group,555	NULL,556};557 558/* end of per-port file structures and support code */559 560/*561 * Start of per-unit (or driver, in some cases, but replicated562 * per unit) functions (these get a device *)563 */564static ssize_t hw_rev_show(struct device *device, struct device_attribute *attr,565			   char *buf)566{567	struct qib_ibdev *dev =568		rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);569 570	return sysfs_emit(buf, "%x\n", dd_from_dev(dev)->minrev);571}572static DEVICE_ATTR_RO(hw_rev);573 574static ssize_t hca_type_show(struct device *device,575			     struct device_attribute *attr, char *buf)576{577	struct qib_ibdev *dev =578		rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);579	struct qib_devdata *dd = dd_from_dev(dev);580 581	if (!dd->boardname)582		return -EINVAL;583	return sysfs_emit(buf, "%s\n", dd->boardname);584}585static DEVICE_ATTR_RO(hca_type);586static DEVICE_ATTR(board_id, 0444, hca_type_show, NULL);587 588static DEVICE_STRING_ATTR_RO(version, 0444, QIB_DRIVER_VERSION);589 590static ssize_t boardversion_show(struct device *device,591				 struct device_attribute *attr, char *buf)592{593	struct qib_ibdev *dev =594		rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);595	struct qib_devdata *dd = dd_from_dev(dev);596 597	/* The string printed here is already newline-terminated. */598	return sysfs_emit(buf, "%s", dd->boardversion);599}600static DEVICE_ATTR_RO(boardversion);601 602static ssize_t localbus_info_show(struct device *device,603				  struct device_attribute *attr, char *buf)604{605	struct qib_ibdev *dev =606		rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);607	struct qib_devdata *dd = dd_from_dev(dev);608 609	/* The string printed here is already newline-terminated. */610	return sysfs_emit(buf, "%s", dd->lbus_info);611}612static DEVICE_ATTR_RO(localbus_info);613 614static ssize_t nctxts_show(struct device *device,615			   struct device_attribute *attr, char *buf)616{617	struct qib_ibdev *dev =618		rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);619	struct qib_devdata *dd = dd_from_dev(dev);620 621	/* Return the number of user ports (contexts) available. */622	/* The calculation below deals with a special case where623	 * cfgctxts is set to 1 on a single-port board. */624	return sysfs_emit(buf, "%u\n",625			  (dd->first_user_ctxt > dd->cfgctxts) ?626				  0 :627				  (dd->cfgctxts - dd->first_user_ctxt));628}629static DEVICE_ATTR_RO(nctxts);630 631static ssize_t nfreectxts_show(struct device *device,632			       struct device_attribute *attr, char *buf)633{634	struct qib_ibdev *dev =635		rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);636	struct qib_devdata *dd = dd_from_dev(dev);637 638	/* Return the number of free user ports (contexts) available. */639	return sysfs_emit(buf, "%u\n", dd->freectxts);640}641static DEVICE_ATTR_RO(nfreectxts);642 643static ssize_t serial_show(struct device *device, struct device_attribute *attr,644			   char *buf)645{646	struct qib_ibdev *dev =647		rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);648	struct qib_devdata *dd = dd_from_dev(dev);649	const u8 *end = memchr(dd->serial, 0, ARRAY_SIZE(dd->serial));650	int size = end ? end - dd->serial : ARRAY_SIZE(dd->serial);651 652	return sysfs_emit(buf, ".%*s\n", size, dd->serial);653}654static DEVICE_ATTR_RO(serial);655 656static ssize_t chip_reset_store(struct device *device,657				struct device_attribute *attr, const char *buf,658				size_t count)659{660	struct qib_ibdev *dev =661		rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);662	struct qib_devdata *dd = dd_from_dev(dev);663	int ret;664 665	if (count < 5 || memcmp(buf, "reset", 5) || !dd->diag_client) {666		ret = -EINVAL;667		goto bail;668	}669 670	ret = qib_reset_device(dd->unit);671bail:672	return ret < 0 ? ret : count;673}674static DEVICE_ATTR_WO(chip_reset);675 676/*677 * Dump tempsense regs. in decimal, to ease shell-scripts.678 */679static ssize_t tempsense_show(struct device *device,680			      struct device_attribute *attr, char *buf)681{682	struct qib_ibdev *dev =683		rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev);684	struct qib_devdata *dd = dd_from_dev(dev);685	int i;686	u8 regvals[8];687 688	for (i = 0; i < 8; i++) {689		int ret;690 691		if (i == 6)692			continue;693		ret = dd->f_tempsense_rd(dd, i);694		if (ret < 0)695			return ret;	/* return error on bad read */696		regvals[i] = ret;697	}698	return sysfs_emit(buf, "%d %d %02X %02X %d %d\n",699			  (signed char)regvals[0],700			  (signed char)regvals[1],701			  regvals[2],702			  regvals[3],703			  (signed char)regvals[5],704			  (signed char)regvals[7]);705}706static DEVICE_ATTR_RO(tempsense);707 708/*709 * end of per-unit (or driver, in some cases, but replicated710 * per unit) functions711 */712 713/* start of per-unit file structures and support code */714static struct attribute *qib_attributes[] = {715	&dev_attr_hw_rev.attr,716	&dev_attr_hca_type.attr,717	&dev_attr_board_id.attr,718	&dev_attr_version.attr.attr,719	&dev_attr_nctxts.attr,720	&dev_attr_nfreectxts.attr,721	&dev_attr_serial.attr,722	&dev_attr_boardversion.attr,723	&dev_attr_tempsense.attr,724	&dev_attr_localbus_info.attr,725	&dev_attr_chip_reset.attr,726	NULL,727};728 729const struct attribute_group qib_attr_group = {730	.attrs = qib_attributes,731};732