⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qeth_sys.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))		return sprintf(buf, "n/a\n");	return sprintf(buf, "%s\n", (card->options.broadcast_mode ==				     QETH_TR_BROADCAST_ALLRINGS)?		       "all rings":"local");}static ssize_tqeth_dev_broadcast_mode_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;	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR))){		PRINT_WARN("Device is not a tokenring device!\n");		return -EINVAL;	}	tmp = strsep((char **) &buf, "\n");	if (!strcmp(tmp, "local")){		card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL;		return count;	} else if (!strcmp(tmp, "all_rings")) {		card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;		return count;	} else {		PRINT_WARN("broadcast_mode: invalid mode %s!\n",			   tmp);		return -EINVAL;	}	return count;}static DEVICE_ATTR(broadcast_mode, 0644, qeth_dev_broadcast_mode_show,		   qeth_dev_broadcast_mode_store);static ssize_tqeth_dev_canonical_macaddr_show(struct device *dev, struct device_attribute *attr, char *buf){	struct qeth_card *card = dev->driver_data;	if (!card)		return -EINVAL;	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))		return sprintf(buf, "n/a\n");	return sprintf(buf, "%i\n", (card->options.macaddr_mode ==				     QETH_TR_MACADDR_CANONICAL)? 1:0);}static ssize_tqeth_dev_canonical_macaddr_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;	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR))){		PRINT_WARN("Device is not a tokenring device!\n");		return -EINVAL;	}	i = simple_strtoul(buf, &tmp, 16);	if ((i == 0) || (i == 1))		card->options.macaddr_mode = i?			QETH_TR_MACADDR_CANONICAL :			QETH_TR_MACADDR_NONCANONICAL;	else {		PRINT_WARN("canonical_macaddr: write 0 or 1 to this file!\n");		return -EINVAL;	}	return count;}static DEVICE_ATTR(canonical_macaddr, 0644, qeth_dev_canonical_macaddr_show,		   qeth_dev_canonical_macaddr_store);static ssize_tqeth_dev_layer2_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.layer2 ? 1:0);}static ssize_tqeth_dev_layer2_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->info.type == QETH_CARD_TYPE_IQD) {                PRINT_WARN("Layer2 on Hipersockets is not supported! \n");                return -EPERM;        }	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.layer2 = i;	else {		PRINT_WARN("layer2: write 0 or 1 to this file!\n");		return -EINVAL;	}	return count;}static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,		   qeth_dev_layer2_store);static ssize_tqeth_dev_large_send_show(struct device *dev, struct device_attribute *attr, char *buf){	struct qeth_card *card = dev->driver_data;	if (!card)		return -EINVAL;	switch (card->options.large_send) {	case QETH_LARGE_SEND_NO:		return sprintf(buf, "%s\n", "no");	case QETH_LARGE_SEND_EDDP:		return sprintf(buf, "%s\n", "EDDP");	case QETH_LARGE_SEND_TSO:		return sprintf(buf, "%s\n", "TSO");	default:		return sprintf(buf, "%s\n", "N/A");	}}static ssize_tqeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){	struct qeth_card *card = dev->driver_data;	enum qeth_large_send_types type;	int rc = 0;	char *tmp;	if (!card)		return -EINVAL;	tmp = strsep((char **) &buf, "\n");	if (!strcmp(tmp, "no")){		type = QETH_LARGE_SEND_NO;	} else if (!strcmp(tmp, "EDDP")) {		type = QETH_LARGE_SEND_EDDP;	} else if (!strcmp(tmp, "TSO")) {		type = QETH_LARGE_SEND_TSO;	} else {		PRINT_WARN("large_send: invalid mode %s!\n", tmp);		return -EINVAL;	}	if (card->options.large_send == type)		return count;	if ((rc = qeth_set_large_send(card, type)))			return rc;	return count;}static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show,		   qeth_dev_large_send_store);static ssize_tqeth_dev_blkt_show(char *buf, struct qeth_card *card, int value ){	if (!card)		return -EINVAL;	return sprintf(buf, "%i\n", value);}static ssize_tqeth_dev_blkt_store(struct qeth_card *card, const char *buf, size_t count,			  int *value, int max_value){	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 <= max_value) {		*value = i;	} else {		PRINT_WARN("blkt total time: write values between"			   " 0 and %d to this file!\n", max_value);		return -EINVAL;	}	return count;}static ssize_tqeth_dev_blkt_total_show(struct device *dev, struct device_attribute *attr, char *buf){	struct qeth_card *card = dev->driver_data;	return qeth_dev_blkt_show(buf, card, card->info.blkt.time_total);}static ssize_tqeth_dev_blkt_total_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){	struct qeth_card *card = dev->driver_data;	return qeth_dev_blkt_store(card, buf, count,				   &card->info.blkt.time_total,1000);}static DEVICE_ATTR(total, 0644, qeth_dev_blkt_total_show,		   qeth_dev_blkt_total_store);static ssize_tqeth_dev_blkt_inter_show(struct device *dev, struct device_attribute *attr, char *buf){	struct qeth_card *card = dev->driver_data;	return qeth_dev_blkt_show(buf, card, card->info.blkt.inter_packet);}static ssize_tqeth_dev_blkt_inter_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){	struct qeth_card *card = dev->driver_data;	return qeth_dev_blkt_store(card, buf, count,				   &card->info.blkt.inter_packet,100);}static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,		   qeth_dev_blkt_inter_store);static ssize_tqeth_dev_blkt_inter_jumbo_show(struct device *dev, struct device_attribute *attr, char *buf){	struct qeth_card *card = dev->driver_data;	return qeth_dev_blkt_show(buf, card,				  card->info.blkt.inter_packet_jumbo);}static ssize_tqeth_dev_blkt_inter_jumbo_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){	struct qeth_card *card = dev->driver_data;	return qeth_dev_blkt_store(card, buf, count,				   &card->info.blkt.inter_packet_jumbo,100);}static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,		   qeth_dev_blkt_inter_jumbo_store);static struct device_attribute * qeth_blkt_device_attrs[] = {	&dev_attr_total,	&dev_attr_inter,	&dev_attr_inter_jumbo,	NULL,};static struct attribute_group qeth_device_blkt_group = {	.name = "blkt",	.attrs = (struct attribute **)qeth_blkt_device_attrs,};static struct device_attribute * qeth_device_attrs[] = {	&dev_attr_state,	&dev_attr_chpid,	&dev_attr_if_name,	&dev_attr_card_type,	&dev_attr_portno,	&dev_attr_portname,	&dev_attr_checksumming,	&dev_attr_priority_queueing,	&dev_attr_buffer_count,	&dev_attr_route4,#ifdef CONFIG_QETH_IPV6	&dev_attr_route6,#endif	&dev_attr_add_hhlen,	&dev_attr_fake_ll,	&dev_attr_fake_broadcast,	&dev_attr_recover,	&dev_attr_broadcast_mode,	&dev_attr_canonical_macaddr,	&dev_attr_layer2,	&dev_attr_large_send,	NULL,};static struct attribute_group qeth_device_attr_group = {	.attrs = (struct attribute **)qeth_device_attrs,};static struct device_attribute * qeth_osn_device_attrs[] = {	&dev_attr_state,	&dev_attr_chpid,	&dev_attr_if_name,	&dev_attr_card_type,	&dev_attr_buffer_count,	&dev_attr_recover,	NULL,};static struct attribute_group qeth_osn_device_attr_group = {	.attrs = (struct attribute **)qeth_osn_device_attrs,};#define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store)			     \struct device_attribute dev_attr_##_id = {				     \	.attr = {.name=__stringify(_name), .mode=_mode, .owner=THIS_MODULE },\	.show	= _show,						     \	.store	= _store,						     \};intqeth_check_layer2(struct qeth_card *card){	if (card->options.layer2)		return -EPERM;	return 0;}static ssize_tqeth_dev_ipato_enable_show(struct device *dev, struct device_attribute *attr, char *buf){	struct qeth_card *card = dev->driver_data;	if (!card)		return -EINVAL;	if (qeth_check_layer2(card))		return -EPERM;	return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);}static ssize_tqeth_dev_ipato_enable_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;	if (qeth_check_layer2(card))		return -EPERM;	tmp = strsep((char **) &buf, "\n");	if (!strcmp(tmp, "toggle")){		card->ipato.enabled = (card->ipato.enabled)? 0 : 1;	} else if (!strcmp(tmp, "1")){		card->ipato.enabled = 1;	} else if (!strcmp(tmp, "0")){		card->ipato.enabled = 0;	} else {		PRINT_WARN("ipato_enable: write 0, 1 or 'toggle' to "			   "this file\n");		return -EINVAL;	}	return count;}static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,			qeth_dev_ipato_enable_show,			qeth_dev_ipato_enable_store);static ssize_tqeth_dev_ipato_invert4_show(struct device *dev, struct device_attribute *attr, char *buf){	struct qeth_card *card = dev->driver_data;	if (!card)		return -EINVAL;	if (qeth_check_layer2(card))		return -EPERM;	return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);}static ssize_tqeth_dev_ipato_invert4_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 (qeth_check_layer2(card))		return -EPERM;	tmp = strsep((char **) &buf, "\n");	if (!strcmp(tmp, "toggle")){		card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;	} else if (!strcmp(tmp, "1")){		card->ipato.invert4 = 1;	} else if (!strcmp(tmp, "0")){		card->ipato.invert4 = 0;	} else {		PRINT_WARN("ipato_invert4: write 0, 1 or 'toggle' to "			   "this file\n");		return -EINVAL;	}	return count;}static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,			qeth_dev_ipato_invert4_show,			qeth_dev_ipato_invert4_store);static inline ssize_tqeth_dev_ipato_add_show(char *buf, struct qeth_card *card,			enum qeth_prot_versions proto){	struct qeth_ipato_entry *ipatoe;	unsigned long flags;	char addr_str[40];	int entry_len; /* length of 1 entry string, differs between v4 and v6 */	int i = 0;	if (qeth_check_layer2(card))		return -EPERM;	entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;	/* add strlen for "/<mask>\n" */	entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;	spin_lock_irqsave(&card->ip_lock, flags);	list_for_each_entry(ipatoe, &card->ipato.entries, entry){		if (ipatoe->proto != proto)			continue;		/* String must not be longer than PAGE_SIZE. So we check if		 * string length gets near PAGE_SIZE. Then we can savely display		 * the next IPv6 address (worst case, compared to IPv4) */		if ((PAGE_SIZE - i) <= entry_len)			break;		qeth_ipaddr_to_string(proto, ipatoe->addr, addr_str);		i += snprintf(buf + i, PAGE_SIZE - i,			      "%s/%i\n", addr_str, ipatoe->mask_bits);	}	spin_unlock_irqrestore(&card->ip_lock, flags);	i += snprintf(buf + i, PAGE_SIZE - i, "\n");	return i;}static ssize_tqeth_dev_ipato_add4_show(struct device *dev, struct device_attribute *attr, char *buf){	struct qeth_card *card = dev->driver_data;	if (!card)		return -EINVAL;	return qeth_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);}static inline intqeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,		  u8 *addr, int *mask_bits){	const char *start, *end;	char *tmp;	char buffer[49] = {0, };	start = buf;	/* get address string */	end = strchr(start, '/');	if (!end || (end-start >= 49)){		PRINT_WARN("Invalid format for ipato_addx/delx. "			   "Use <ip addr>/<mask bits>\n");		return -EINVAL;	}	strncpy(buffer, start, end - start);	if (qeth_string_to_ipaddr(buffer, proto, addr)){		PRINT_WARN("Invalid IP address format!\n");		return -EINVAL;	}	start = end + 1;	*mask_bits = simple_strtoul(start, &tmp, 10);	return 0;}static inline ssize_tqeth_dev_ipato_add_store(const char *buf, size_t count,			 struct qeth_card *card, enum qeth_prot_versions proto){	struct qeth_ipato_entry *ipatoe;	u8 addr[16];	int mask_bits;	int rc;	if (qeth_check_layer2(card))		return -EPERM;	if ((rc = qeth_parse_ipatoe(buf, proto, addr, &mask_bits)))		return rc;	if (!(ipatoe = kmalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL))){		PRINT_WARN("No memory to allocate ipato entry\n");		return -ENOMEM;	}	memset(ipatoe, 0, sizeof(struct qeth_ipato_entry));	ipatoe->proto = proto;	memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);	ipatoe->mask_bits = mask_bits;	if ((rc = qeth_add_ipato_entry(card, ipatoe))){		kfree(ipatoe);		return rc;	}	return count;}static ssize_tqeth_dev_ipato_add4_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_ipato_add_store(buf, count, card, QETH_PROT_IPV4);}static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,			qeth_dev_ipato_add4_show,			qeth_dev_ipato_add4_store);static inline ssize_tqeth_dev_ipato_del_store(const char *buf, size_t count,			 struct qeth_card *card, enum qeth_prot_versions proto){	u8 addr[16];	int mask_bits;	int rc;	if (qeth_check_layer2(card))		return -EPERM;	if ((rc = qeth_parse_ipatoe(buf, proto, addr, &mask_bits)))		return rc;	qeth_del_ipato_entry(card, proto, addr, mask_bits);	return count;}static ssize_tqeth_dev_ipato_del4_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_ipato_del_store(buf, count, card, QETH_PROT_IPV4);

⌨️ 快捷键说明

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