ipath_sysfs.c

来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 791 行 · 第 1/2 页

C
791
字号
/* * Copyright (c) 2006 PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses.  You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * *     Redistribution and use in source and binary forms, with or *     without modification, are permitted provided that the following *     conditions are met: * *      - Redistributions of source code must retain the above *        copyright notice, this list of conditions and the following *        disclaimer. * *      - Redistributions in binary form must reproduce the above *        copyright notice, this list of conditions and the following *        disclaimer in the documentation and/or other materials *        provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */#include <linux/ctype.h>#include <linux/pci.h>#include "ipath_kernel.h"#include "ips_common.h"#include "ipath_layer.h"/** * ipath_parse_ushort - parse an unsigned short value in an arbitrary base * @str: the string containing the number * @valp: where to put the result * * returns the number of bytes consumed, or negative value on error */int ipath_parse_ushort(const char *str, unsigned short *valp){	unsigned long val;	char *end;	int ret;	if (!isdigit(str[0])) {		ret = -EINVAL;		goto bail;	}	val = simple_strtoul(str, &end, 0);	if (val > 0xffff) {		ret = -EINVAL;		goto bail;	}	*valp = val;	ret = end + 1 - str;	if (ret == 0)		ret = -EINVAL;bail:	return ret;}static ssize_t show_version(struct device_driver *dev, char *buf){	/* The string printed here is already newline-terminated. */	return scnprintf(buf, PAGE_SIZE, "%s", ipath_core_version);}static ssize_t show_num_units(struct device_driver *dev, char *buf){	return scnprintf(buf, PAGE_SIZE, "%d\n",			 ipath_count_units(NULL, NULL, NULL));}#define DRIVER_STAT(name, attr) \	static ssize_t show_stat_##name(struct device_driver *dev, \					char *buf) \	{ \		return scnprintf( \			buf, PAGE_SIZE, "%llu\n", \			(unsigned long long) ipath_stats.sps_ ##attr); \	} \	static DRIVER_ATTR(name, S_IRUGO, show_stat_##name, NULL)DRIVER_STAT(intrs, ints);DRIVER_STAT(err_intrs, errints);DRIVER_STAT(errs, errs);DRIVER_STAT(pkt_errs, pkterrs);DRIVER_STAT(crc_errs, crcerrs);DRIVER_STAT(hw_errs, hwerrs);DRIVER_STAT(ib_link, iblink);DRIVER_STAT(port0_pkts, port0pkts);DRIVER_STAT(ether_spkts, ether_spkts);DRIVER_STAT(ether_rpkts, ether_rpkts);DRIVER_STAT(sma_spkts, sma_spkts);DRIVER_STAT(sma_rpkts, sma_rpkts);DRIVER_STAT(hdrq_full, hdrqfull);DRIVER_STAT(etid_full, etidfull);DRIVER_STAT(no_piobufs, nopiobufs);DRIVER_STAT(ports, ports);DRIVER_STAT(pkey0, pkeys[0]);DRIVER_STAT(pkey1, pkeys[1]);DRIVER_STAT(pkey2, pkeys[2]);DRIVER_STAT(pkey3, pkeys[3]);/* XXX fix the following when dynamic table of devices used */DRIVER_STAT(lid0, lid[0]);DRIVER_STAT(lid1, lid[1]);DRIVER_STAT(lid2, lid[2]);DRIVER_STAT(lid3, lid[3]);DRIVER_STAT(nports, nports);DRIVER_STAT(null_intr, nullintr);DRIVER_STAT(max_pkts_call, maxpkts_call);DRIVER_STAT(avg_pkts_call, avgpkts_call);DRIVER_STAT(page_locks, pagelocks);DRIVER_STAT(page_unlocks, pageunlocks);DRIVER_STAT(krdrops, krdrops);/* XXX fix the following when dynamic table of devices used */DRIVER_STAT(mlid0, mlid[0]);DRIVER_STAT(mlid1, mlid[1]);DRIVER_STAT(mlid2, mlid[2]);DRIVER_STAT(mlid3, mlid[3]);static struct attribute *driver_stat_attributes[] = {	&driver_attr_intrs.attr,	&driver_attr_err_intrs.attr,	&driver_attr_errs.attr,	&driver_attr_pkt_errs.attr,	&driver_attr_crc_errs.attr,	&driver_attr_hw_errs.attr,	&driver_attr_ib_link.attr,	&driver_attr_port0_pkts.attr,	&driver_attr_ether_spkts.attr,	&driver_attr_ether_rpkts.attr,	&driver_attr_sma_spkts.attr,	&driver_attr_sma_rpkts.attr,	&driver_attr_hdrq_full.attr,	&driver_attr_etid_full.attr,	&driver_attr_no_piobufs.attr,	&driver_attr_ports.attr,	&driver_attr_pkey0.attr,	&driver_attr_pkey1.attr,	&driver_attr_pkey2.attr,	&driver_attr_pkey3.attr,	&driver_attr_lid0.attr,	&driver_attr_lid1.attr,	&driver_attr_lid2.attr,	&driver_attr_lid3.attr,	&driver_attr_nports.attr,	&driver_attr_null_intr.attr,	&driver_attr_max_pkts_call.attr,	&driver_attr_avg_pkts_call.attr,	&driver_attr_page_locks.attr,	&driver_attr_page_unlocks.attr,	&driver_attr_krdrops.attr,	&driver_attr_mlid0.attr,	&driver_attr_mlid1.attr,	&driver_attr_mlid2.attr,	&driver_attr_mlid3.attr,	NULL};static struct attribute_group driver_stat_attr_group = {	.name = "stats",	.attrs = driver_stat_attributes};static ssize_t show_status(struct device *dev,			   struct device_attribute *attr,			   char *buf){	struct ipath_devdata *dd = dev_get_drvdata(dev);	ssize_t ret;	if (!dd->ipath_statusp) {		ret = -EINVAL;		goto bail;	}	ret = scnprintf(buf, PAGE_SIZE, "0x%llx\n",			(unsigned long long) *(dd->ipath_statusp));bail:	return ret;}static const char *ipath_status_str[] = {	"Initted",	"Disabled",	"Admin_Disabled",	"OIB_SMA",	"SMA",	"Present",	"IB_link_up",	"IB_configured",	"NoIBcable",	"Fatal_Hardware_Error",	NULL,};static ssize_t show_status_str(struct device *dev,			       struct device_attribute *attr,			       char *buf){	struct ipath_devdata *dd = dev_get_drvdata(dev);	int i, any;	u64 s;	ssize_t ret;	if (!dd->ipath_statusp) {		ret = -EINVAL;		goto bail;	}	s = *(dd->ipath_statusp);	*buf = '\0';	for (any = i = 0; s && ipath_status_str[i]; i++) {		if (s & 1) {			if (any && strlcat(buf, " ", PAGE_SIZE) >=			    PAGE_SIZE)				/* overflow */				break;			if (strlcat(buf, ipath_status_str[i],				    PAGE_SIZE) >= PAGE_SIZE)				break;			any = 1;		}		s >>= 1;	}	if (any)		strlcat(buf, "\n", PAGE_SIZE);	ret = strlen(buf);bail:	return ret;}static ssize_t show_boardversion(struct device *dev,			       struct device_attribute *attr,			       char *buf){	struct ipath_devdata *dd = dev_get_drvdata(dev);	/* The string printed here is already newline-terminated. */	return scnprintf(buf, PAGE_SIZE, "%s", dd->ipath_boardversion);}static ssize_t show_lid(struct device *dev,			struct device_attribute *attr,			char *buf){	struct ipath_devdata *dd = dev_get_drvdata(dev);	return scnprintf(buf, PAGE_SIZE, "0x%x\n", dd->ipath_lid);}static ssize_t store_lid(struct device *dev,			 struct device_attribute *attr,			  const char *buf,			  size_t count){	struct ipath_devdata *dd = dev_get_drvdata(dev);	u16 lid;	int ret;	ret = ipath_parse_ushort(buf, &lid);	if (ret < 0)		goto invalid;	if (lid == 0 || lid >= 0xc000) {		ret = -EINVAL;		goto invalid;	}	ipath_set_sps_lid(dd, lid, 0);	goto bail;invalid:	ipath_dev_err(dd, "attempt to set invalid LID\n");bail:	return ret;}static ssize_t show_mlid(struct device *dev,			 struct device_attribute *attr,			 char *buf){	struct ipath_devdata *dd = dev_get_drvdata(dev);	return scnprintf(buf, PAGE_SIZE, "0x%x\n", dd->ipath_mlid);}static ssize_t store_mlid(struct device *dev,			 struct device_attribute *attr,			  const char *buf,			  size_t count){	struct ipath_devdata *dd = dev_get_drvdata(dev);	int unit;	u16 mlid;	int ret;	ret = ipath_parse_ushort(buf, &mlid);	if (ret < 0)		goto invalid;	unit = dd->ipath_unit;	dd->ipath_mlid = mlid;	ipath_stats.sps_mlid[unit] = mlid;	ipath_layer_intr(dd, IPATH_LAYER_INT_BCAST);	goto bail;invalid:	ipath_dev_err(dd, "attempt to set invalid MLID\n");bail:	return ret;}static ssize_t show_guid(struct device *dev,			 struct device_attribute *attr,			 char *buf){	struct ipath_devdata *dd = dev_get_drvdata(dev);	u8 *guid;	guid = (u8 *) & (dd->ipath_guid);	return scnprintf(buf, PAGE_SIZE,			 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",			 guid[0], guid[1], guid[2], guid[3],			 guid[4], guid[5], guid[6], guid[7]);}static ssize_t store_guid(struct device *dev,			 struct device_attribute *attr,			  const char *buf,			  size_t count){	struct ipath_devdata *dd = dev_get_drvdata(dev);	ssize_t ret;	unsigned short guid[8];	__be64 nguid;	u8 *ng;	int i;	if (sscanf(buf, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",		   &guid[0], &guid[1], &guid[2], &guid[3],		   &guid[4], &guid[5], &guid[6], &guid[7]) != 8)		goto invalid;	ng = (u8 *) &nguid;	for (i = 0; i < 8; i++) {		if (guid[i] > 0xff)			goto invalid;		ng[i] = guid[i];	}	dd->ipath_guid = nguid;	dd->ipath_nguid = 1;	ret = strlen(buf);	goto bail;invalid:	ipath_dev_err(dd, "attempt to set invalid GUID\n");	ret = -EINVAL;bail:	return ret;}static ssize_t show_nguid(struct device *dev,			  struct device_attribute *attr,			  char *buf){	struct ipath_devdata *dd = dev_get_drvdata(dev);	return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_nguid);}static ssize_t show_serial(struct device *dev,			   struct device_attribute *attr,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?