ipath_sysfs.c
来自「linux 内核源代码」· C语言 代码 · 共 807 行 · 第 1/2 页
C
807 行
/* * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved. * 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 "ipath_kernel.h"#include "ipath_common.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", ib_ipath_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));}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", "", /* This used to be the old "OIB_SMA" status. */ "", /* This used to be the old "SMA" status. */ "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_lmc(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_lmc);}static ssize_t store_lmc(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct ipath_devdata *dd = dev_get_drvdata(dev); u16 lmc = 0; int ret; ret = ipath_parse_ushort(buf, &lmc); if (ret < 0) goto invalid; if (lmc > 7) { ret = -EINVAL; goto invalid; } ipath_set_lid(dd, dd->ipath_lid, lmc); goto bail;invalid: ipath_dev_err(dd, "attempt to set invalid LMC %u\n", lmc);bail: return ret;}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 = 0; int ret; ret = ipath_parse_ushort(buf, &lid); if (ret < 0) goto invalid; if (lid == 0 || lid >= IPATH_MULTICAST_LID_BASE) { ret = -EINVAL; goto invalid; } ipath_set_lid(dd, lid, dd->ipath_lmc); goto bail;invalid: ipath_dev_err(dd, "attempt to set invalid LID 0x%x\n", lid);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); u16 mlid; int ret; ret = ipath_parse_ushort(buf, &mlid); if (ret < 0 || mlid < IPATH_MULTICAST_LID_BASE) goto invalid; dd->ipath_mlid = mlid; 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 new_guid; 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 *) &new_guid; for (i = 0; i < 8; i++) { if (guid[i] > 0xff) goto invalid; ng[i] = guid[i]; } if (new_guid == 0) goto invalid; dd->ipath_guid = new_guid; 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_nports(struct device *dev, struct device_attribute *attr, char *buf){ struct ipath_devdata *dd = dev_get_drvdata(dev); /* Return the number of user ports available. */ return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_cfgports - 1);}static ssize_t show_serial(struct device *dev, struct device_attribute *attr, char *buf){ struct ipath_devdata *dd = dev_get_drvdata(dev); buf[sizeof dd->ipath_serial] = '\0'; memcpy(buf, dd->ipath_serial, sizeof dd->ipath_serial); strcat(buf, "\n"); return strlen(buf);}static ssize_t show_unit(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_unit);}#define DEVICE_COUNTER(name, attr) \ static ssize_t show_counter_##name(struct device *dev, \ struct device_attribute *attr, \ char *buf) \ { \ struct ipath_devdata *dd = dev_get_drvdata(dev); \ return scnprintf(\ buf, PAGE_SIZE, "%llu\n", (unsigned long long) \ ipath_snap_cntr( \ dd, offsetof(struct infinipath_counters, \ attr) / sizeof(u64))); \ } \ static DEVICE_ATTR(name, S_IRUGO, show_counter_##name, NULL);DEVICE_COUNTER(ib_link_downeds, IBLinkDownedCnt);DEVICE_COUNTER(ib_link_err_recoveries, IBLinkErrRecoveryCnt);DEVICE_COUNTER(ib_status_changes, IBStatusChangeCnt);DEVICE_COUNTER(ib_symbol_errs, IBSymbolErrCnt);DEVICE_COUNTER(lb_flow_stalls, LBFlowStallCnt);DEVICE_COUNTER(lb_ints, LBIntCnt);DEVICE_COUNTER(rx_bad_formats, RxBadFormatCnt);DEVICE_COUNTER(rx_buf_ovfls, RxBufOvflCnt);DEVICE_COUNTER(rx_data_pkts, RxDataPktCnt);DEVICE_COUNTER(rx_dropped_pkts, RxDroppedPktCnt);DEVICE_COUNTER(rx_dwords, RxDwordCnt);DEVICE_COUNTER(rx_ebps, RxEBPCnt);DEVICE_COUNTER(rx_flow_ctrl_errs, RxFlowCtrlErrCnt);DEVICE_COUNTER(rx_flow_pkts, RxFlowPktCnt);DEVICE_COUNTER(rx_icrc_errs, RxICRCErrCnt);DEVICE_COUNTER(rx_len_errs, RxLenErrCnt);DEVICE_COUNTER(rx_link_problems, RxLinkProblemCnt);DEVICE_COUNTER(rx_lpcrc_errs, RxLPCRCErrCnt);DEVICE_COUNTER(rx_max_min_len_errs, RxMaxMinLenErrCnt);DEVICE_COUNTER(rx_p0_hdr_egr_ovfls, RxP0HdrEgrOvflCnt);DEVICE_COUNTER(rx_p1_hdr_egr_ovfls, RxP1HdrEgrOvflCnt);DEVICE_COUNTER(rx_p2_hdr_egr_ovfls, RxP2HdrEgrOvflCnt);DEVICE_COUNTER(rx_p3_hdr_egr_ovfls, RxP3HdrEgrOvflCnt);DEVICE_COUNTER(rx_p4_hdr_egr_ovfls, RxP4HdrEgrOvflCnt);DEVICE_COUNTER(rx_p5_hdr_egr_ovfls, RxP5HdrEgrOvflCnt);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?