📄 qeth_sys.c
字号:
/* * * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.60 $) * * Linux on zSeries OSA Express and HiperSockets support * This file contains code related to sysfs. * * Copyright 2000,2003 IBM Corporation * * Author(s): Thomas Spatzier <tspat@de.ibm.com> * Frank Pavlic <fpavlic@de.ibm.com> * */#include <linux/list.h>#include <linux/rwsem.h>#include <asm/ebcdic.h>#include "qeth.h"#include "qeth_mpc.h"#include "qeth_fs.h"const char *VERSION_QETH_SYS_C = "$Revision: 1.60 $";/*****************************************************************************//* *//* /sys-fs stuff UNDER DEVELOPMENT !!! *//* *//*****************************************************************************///low/high watermarkstatic ssize_tqeth_dev_state_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; switch (card->state) { case CARD_STATE_DOWN: return sprintf(buf, "DOWN\n"); case CARD_STATE_HARDSETUP: return sprintf(buf, "HARDSETUP\n"); case CARD_STATE_SOFTSETUP: return sprintf(buf, "SOFTSETUP\n"); case CARD_STATE_UP: if (card->lan_online) return sprintf(buf, "UP (LAN ONLINE)\n"); else return sprintf(buf, "UP (LAN OFFLINE)\n"); case CARD_STATE_RECOVER: return sprintf(buf, "RECOVER\n"); default: return sprintf(buf, "UNKNOWN\n"); }}static DEVICE_ATTR(state, 0444, qeth_dev_state_show, NULL);static ssize_tqeth_dev_chpid_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; return sprintf(buf, "%02X\n", card->info.chpid);}static DEVICE_ATTR(chpid, 0444, qeth_dev_chpid_show, NULL);static ssize_tqeth_dev_if_name_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; return sprintf(buf, "%s\n", QETH_CARD_IFNAME(card));}static DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL);static ssize_tqeth_dev_card_type_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; return sprintf(buf, "%s\n", qeth_get_cardname_short(card));}static DEVICE_ATTR(card_type, 0444, qeth_dev_card_type_show, NULL);static ssize_tqeth_dev_portno_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; return sprintf(buf, "%i\n", card->info.portno);}static ssize_tqeth_dev_portno_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct qeth_card *card = dev->driver_data; char *tmp; unsigned int portno; if (!card) return -EINVAL; if ((card->state != CARD_STATE_DOWN) && (card->state != CARD_STATE_RECOVER)) return -EPERM; portno = simple_strtoul(buf, &tmp, 16); if ((portno < 0) || (portno > MAX_PORTNO)){ PRINT_WARN("portno 0x%X is out of range\n", portno); return -EINVAL; } card->info.portno = portno; return count;}static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);static ssize_tqeth_dev_portname_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; char portname[9] = {0, }; if (!card) return -EINVAL; if (card->info.portname_required) { memcpy(portname, card->info.portname + 1, 8); EBCASC(portname, 8); return sprintf(buf, "%s\n", portname); } else return sprintf(buf, "no portname required\n");}static ssize_tqeth_dev_portname_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct qeth_card *card = dev->driver_data; char *tmp; int i; if (!card) return -EINVAL; if ((card->state != CARD_STATE_DOWN) && (card->state != CARD_STATE_RECOVER)) return -EPERM; tmp = strsep((char **) &buf, "\n"); if ((strlen(tmp) > 8) || (strlen(tmp) == 0)) return -EINVAL; card->info.portname[0] = strlen(tmp); /* for beauty reasons */ for (i = 1; i < 9; i++) card->info.portname[i] = ' '; strcpy(card->info.portname + 1, tmp); ASCEBC(card->info.portname + 1, 8); return count;}static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show, qeth_dev_portname_store);static ssize_tqeth_dev_checksum_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; return sprintf(buf, "%s checksumming\n", qeth_get_checksum_str(card));}static ssize_tqeth_dev_checksum_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct qeth_card *card = dev->driver_data; char *tmp; if (!card) return -EINVAL; if ((card->state != CARD_STATE_DOWN) && (card->state != CARD_STATE_RECOVER)) return -EPERM; tmp = strsep((char **) &buf, "\n"); if (!strcmp(tmp, "sw_checksumming")) card->options.checksum_type = SW_CHECKSUMMING; else if (!strcmp(tmp, "hw_checksumming")) card->options.checksum_type = HW_CHECKSUMMING; else if (!strcmp(tmp, "no_checksumming")) card->options.checksum_type = NO_CHECKSUMMING; else { PRINT_WARN("Unknown checksumming type '%s'\n", tmp); return -EINVAL; } return count;}static DEVICE_ATTR(checksumming, 0644, qeth_dev_checksum_show, qeth_dev_checksum_store);static ssize_tqeth_dev_prioqing_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; switch (card->qdio.do_prio_queueing) { case QETH_PRIO_Q_ING_PREC: return sprintf(buf, "%s\n", "by precedence"); case QETH_PRIO_Q_ING_TOS: return sprintf(buf, "%s\n", "by type of service"); default: return sprintf(buf, "always queue %i\n", card->qdio.default_out_queue); }}static ssize_tqeth_dev_prioqing_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct qeth_card *card = dev->driver_data; char *tmp; if (!card) return -EINVAL; if ((card->state != CARD_STATE_DOWN) && (card->state != CARD_STATE_RECOVER)) return -EPERM; /* check if 1920 devices are supported , * if though we have to permit priority queueing */ if (card->qdio.no_out_queues == 1) { PRINT_WARN("Priority queueing disabled due " "to hardware limitations!\n"); card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; return -EPERM; } tmp = strsep((char **) &buf, "\n"); if (!strcmp(tmp, "prio_queueing_prec")) card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC; else if (!strcmp(tmp, "prio_queueing_tos")) card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS; else if (!strcmp(tmp, "no_prio_queueing:0")) { card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; card->qdio.default_out_queue = 0; } else if (!strcmp(tmp, "no_prio_queueing:1")) { card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; card->qdio.default_out_queue = 1; } else if (!strcmp(tmp, "no_prio_queueing:2")) { card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; card->qdio.default_out_queue = 2; } else if (!strcmp(tmp, "no_prio_queueing:3")) { card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; card->qdio.default_out_queue = 3; } else if (!strcmp(tmp, "no_prio_queueing")) { card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; } else { PRINT_WARN("Unknown queueing type '%s'\n", tmp); return -EINVAL; } return count;}static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show, qeth_dev_prioqing_store);static ssize_tqeth_dev_bufcnt_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; return sprintf(buf, "%i\n", card->qdio.in_buf_pool.buf_count);}static ssize_tqeth_dev_bufcnt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct qeth_card *card = dev->driver_data; char *tmp; int cnt, old_cnt; int rc; if (!card) return -EINVAL; if ((card->state != CARD_STATE_DOWN) && (card->state != CARD_STATE_RECOVER)) return -EPERM; old_cnt = card->qdio.in_buf_pool.buf_count; cnt = simple_strtoul(buf, &tmp, 10); cnt = (cnt < QETH_IN_BUF_COUNT_MIN) ? QETH_IN_BUF_COUNT_MIN : ((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt); if (old_cnt != cnt) { if ((rc = qeth_realloc_buffer_pool(card, cnt))) PRINT_WARN("Error (%d) while setting " "buffer count.\n", rc); } return count;}static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show, qeth_dev_bufcnt_store);static inline ssize_tqeth_dev_route_show(struct qeth_card *card, struct qeth_routing_info *route, char *buf){ switch (route->type) { case PRIMARY_ROUTER: return sprintf(buf, "%s\n", "primary router"); case SECONDARY_ROUTER: return sprintf(buf, "%s\n", "secondary router"); case MULTICAST_ROUTER: if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO) return sprintf(buf, "%s\n", "multicast router+"); else return sprintf(buf, "%s\n", "multicast router"); case PRIMARY_CONNECTOR: if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO) return sprintf(buf, "%s\n", "primary connector+"); else return sprintf(buf, "%s\n", "primary connector"); case SECONDARY_CONNECTOR: if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO) return sprintf(buf, "%s\n", "secondary connector+"); else return sprintf(buf, "%s\n", "secondary connector"); default: return sprintf(buf, "%s\n", "no"); }}static ssize_tqeth_dev_route4_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; return qeth_dev_route_show(card, &card->options.route4, buf);}static inline ssize_tqeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route, enum qeth_prot_versions prot, const char *buf, size_t count){ enum qeth_routing_types old_route_type = route->type; char *tmp; int rc; tmp = strsep((char **) &buf, "\n"); if (!strcmp(tmp, "no_router")){ route->type = NO_ROUTER; } else if (!strcmp(tmp, "primary_connector")) { route->type = PRIMARY_CONNECTOR; } else if (!strcmp(tmp, "secondary_connector")) { route->type = SECONDARY_CONNECTOR; } else if (!strcmp(tmp, "multicast_router")) { route->type = MULTICAST_ROUTER; } else if (!strcmp(tmp, "primary_router")) { route->type = PRIMARY_ROUTER; } else if (!strcmp(tmp, "secondary_router")) { route->type = SECONDARY_ROUTER; } else if (!strcmp(tmp, "multicast_router")) { route->type = MULTICAST_ROUTER; } else { PRINT_WARN("Invalid routing type '%s'.\n", tmp); return -EINVAL; } if (((card->state == CARD_STATE_SOFTSETUP) || (card->state == CARD_STATE_UP)) && (old_route_type != route->type)){ if (prot == QETH_PROT_IPV4) rc = qeth_setrouting_v4(card); else if (prot == QETH_PROT_IPV6) rc = qeth_setrouting_v6(card); } return count;}static ssize_tqeth_dev_route4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; return qeth_dev_route_store(card, &card->options.route4, QETH_PROT_IPV4, buf, count);}static DEVICE_ATTR(route4, 0644, qeth_dev_route4_show, qeth_dev_route4_store);#ifdef CONFIG_QETH_IPV6static ssize_tqeth_dev_route6_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; if (!qeth_is_supported(card, IPA_IPV6)) return sprintf(buf, "%s\n", "n/a"); return qeth_dev_route_show(card, &card->options.route6, buf);}static ssize_tqeth_dev_route6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; if (!qeth_is_supported(card, IPA_IPV6)){ PRINT_WARN("IPv6 not supported for interface %s.\n" "Routing status no changed.\n", QETH_CARD_IFNAME(card)); return -ENOTSUPP; } return qeth_dev_route_store(card, &card->options.route6, QETH_PROT_IPV6, buf, count);}static DEVICE_ATTR(route6, 0644, qeth_dev_route6_show, qeth_dev_route6_store);#endifstatic ssize_tqeth_dev_add_hhlen_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; return sprintf(buf, "%i\n", card->options.add_hhlen);}static ssize_tqeth_dev_add_hhlen_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct qeth_card *card = dev->driver_data; char *tmp; int i; if (!card) return -EINVAL; if ((card->state != CARD_STATE_DOWN) && (card->state != CARD_STATE_RECOVER)) return -EPERM; i = simple_strtoul(buf, &tmp, 10); if ((i < 0) || (i > MAX_ADD_HHLEN)) { PRINT_WARN("add_hhlen out of range\n"); return -EINVAL; } card->options.add_hhlen = i; return count;}static DEVICE_ATTR(add_hhlen, 0644, qeth_dev_add_hhlen_show, qeth_dev_add_hhlen_store);static ssize_tqeth_dev_fake_ll_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; return sprintf(buf, "%i\n", card->options.fake_ll? 1:0);}static ssize_tqeth_dev_fake_ll_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct qeth_card *card = dev->driver_data; char *tmp; int i; if (!card) return -EINVAL; if ((card->state != CARD_STATE_DOWN) && (card->state != CARD_STATE_RECOVER)) return -EPERM; i = simple_strtoul(buf, &tmp, 16); if ((i != 0) && (i != 1)) { PRINT_WARN("fake_ll: write 0 or 1 to this file!\n"); return -EINVAL; } card->options.fake_ll = i; return count;}static DEVICE_ATTR(fake_ll, 0644, qeth_dev_fake_ll_show, qeth_dev_fake_ll_store);static ssize_tqeth_dev_fake_broadcast_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL; return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);}static ssize_tqeth_dev_fake_broadcast_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct qeth_card *card = dev->driver_data; char *tmp; int i; if (!card) return -EINVAL; if ((card->state != CARD_STATE_DOWN) && (card->state != CARD_STATE_RECOVER)) return -EPERM; i = simple_strtoul(buf, &tmp, 16); if ((i == 0) || (i == 1)) card->options.fake_broadcast = i; else { PRINT_WARN("fake_broadcast: write 0 or 1 to this file!\n"); return -EINVAL; } return count;}static DEVICE_ATTR(fake_broadcast, 0644, qeth_dev_fake_broadcast_show, qeth_dev_fake_broadcast_store);static ssize_tqeth_dev_recover_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct qeth_card *card = dev->driver_data; char *tmp; int i; if (!card) return -EINVAL; if (card->state != CARD_STATE_UP) return -EPERM; i = simple_strtoul(buf, &tmp, 16); if (i == 1) qeth_schedule_recovery(card); return count;}static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);static ssize_tqeth_dev_broadcast_mode_show(struct device *dev, struct device_attribute *attr, char *buf){ struct qeth_card *card = dev->driver_data; if (!card) return -EINVAL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -