Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de2e487f authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Greg Kroah-Hartman
Browse files

staging: silicom: introduce bp_dev_get_idx_bsf() and use it



There are two places where duplicate code is located. Moreover, there is a
custom implementation of the sscanf() functionality. This patch makes code
quite simplier and cleaner.

Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3816a540
Loading
Loading
Loading
Loading
+47 −141
Original line number Diff line number Diff line
/******************************************************************************/
/*                                                                            */
/* Bypass Control utility, Copyright (c) 2005-20011 Silicom                   */
/* Bypass Control utility, Copyright (c) 2005-2011 Silicom                    */
/*                                                                            */
/* This program is free software; you can redistribute it and/or modify       */
/* it under the terms of the GNU General Public License as published by       */
/* the Free Software Foundation, located in the file LICENSE.                 */
/*  Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.          */
/* Copyright(c) 2007 - 2009, 2013 Intel Corporation. All rights reserved.     */
/*                                                                            */
/*                                                                            */
/******************************************************************************/
@@ -124,80 +124,60 @@ int bp_proc_create(void);
int is_bypass_fn(struct bpctl_dev *pbpctl_dev);
int get_dev_idx_bsf(int bus, int slot, int func);

static unsigned long str_to_hex(char *p);
static int bp_get_dev_idx_bsf(struct net_device *dev, int *index)
{
	struct ethtool_drvinfo drvinfo = {0};
	char *buf;
	int bus, slot, func;

	if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo)
		dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
	else
		return -EOPNOTSUPP;

	if (!drvinfo.bus_info)
		return -ENODATA;
	if (!strcmp(drvinfo.bus_info, "N/A"))
		return -ENODATA;

	buf = strchr(drvinfo.bus_info, ':');
	if (!buf)
		return -EINVAL;
	buf++;
	if (sscanf(buf, "%x:%x.%x", &bus, &slot, &func) != 3)
		return -EINVAL;

	*index = get_dev_idx_bsf(bus, slot, func);
	return 0;
}

static int bp_device_event(struct notifier_block *unused,
			   unsigned long event, void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	static struct bpctl_dev *pbpctl_dev, *pbpctl_dev_m;
	int dev_num = 0, ret = 0, ret_d = 0, time_left = 0;

	/* printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); */
	/* return NOTIFY_DONE; */
	if (!dev)
		return NOTIFY_DONE;
	if (event == NETDEV_REGISTER) {
		{
			struct ethtool_drvinfo drvinfo;
			char cbuf[32];
			char *buf = NULL;
			char res[10];
			int i = 0, ifindex, idx_dev = 0;
			int bus = 0, slot = 0, func = 0;
			ifindex = dev->ifindex;

			memset(res, 0, 10);
			memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
	if (event == NETDEV_REGISTER) {
		int idx_dev;

			if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) {
				memset(&drvinfo, 0, sizeof(drvinfo));
				dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
			} else
		if (bp_get_dev_idx_bsf(dev, &idx_dev))
			return NOTIFY_DONE;
			if (!drvinfo.bus_info)
				return NOTIFY_DONE;
			if (!strcmp(drvinfo.bus_info, "N/A"))
				return NOTIFY_DONE;
			memcpy(&cbuf, drvinfo.bus_info, 32);
			buf = &cbuf[0];

			while (*buf++ != ':')
				;
			for (i = 0; i < 10; i++, buf++) {
				if (*buf == ':')
					break;
				res[i] = *buf;

			}
			buf++;
			bus = str_to_hex(res);
			memset(res, 0, 10);

			for (i = 0; i < 10; i++, buf++) {
				if (*buf == '.')
					break;
				res[i] = *buf;

			}
			buf++;
			slot = str_to_hex(res);
			func = str_to_hex(buf);
			idx_dev = get_dev_idx_bsf(bus, slot, func);

			if (idx_dev != -1) {
		if (idx_dev == -1)
			return NOTIFY_DONE;

				bpctl_dev_arr[idx_dev].ifindex = ifindex;
		bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
		bpctl_dev_arr[idx_dev].ndev = dev;

				bypass_proc_remove_dev_sd(&bpctl_dev_arr
							  [idx_dev]);
				bypass_proc_create_dev_sd(&bpctl_dev_arr
							  [idx_dev]);

			}

		}
		bypass_proc_remove_dev_sd(&bpctl_dev_arr[idx_dev]);
		bypass_proc_create_dev_sd(&bpctl_dev_arr[idx_dev]);
		return NOTIFY_DONE;

	}
	if (event == NETDEV_UNREGISTER) {
		int idx_dev = 0;
@@ -5269,36 +5249,6 @@ int get_dev_idx_bsf(int bus, int slot, int func)
	return -1;
}

static void str_low(char *str)
{
	int i;

	for (i = 0; i < strlen(str); i++)
		if ((str[i] >= 65) && (str[i] <= 90))
			str[i] += 32;
}

static unsigned long str_to_hex(char *p)
{
	unsigned long hex = 0;
	unsigned long length = strlen(p), shift = 0;
	unsigned char dig = 0;

	str_low(p);
	length = strlen(p);

	if (length == 0)
		return 0;

	do {
		dig = p[--length];
		dig = dig < 'a' ? (dig - '0') : (dig - 'a' + 0xa);
		hex |= (dig << shift);
		shift += 4;
	} while (length);
	return hex;
}

static int get_dev_idx(int ifindex)
{
	int idx_dev = 0;
@@ -5329,70 +5279,26 @@ static struct bpctl_dev *get_dev_idx_p(int ifindex)

static void if_scan_init(void)
{
	int idx_dev = 0;
	struct net_device *dev;
	int ifindex;

	/* rcu_read_lock(); */
	/* rtnl_lock();     */
	/* rcu_read_lock(); */

	for_each_netdev(&init_net, dev) {
		int idx_dev;

		struct ethtool_drvinfo drvinfo;
		char cbuf[32];
		char *buf = NULL;
		char res[10];
		int i = 0;
		int bus = 0, slot = 0, func = 0;
		ifindex = dev->ifindex;

		memset(res, 0, 10);
		memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));

		if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) {
			memset(&drvinfo, 0, sizeof(drvinfo));
			dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
		} else
			continue;
		if (!strcmp(drvinfo.bus_info, "N/A"))
		if (bp_get_dev_idx_bsf(dev, &idx_dev))
			continue;
		memcpy(&cbuf, drvinfo.bus_info, 32);
		buf = &cbuf[0];

		while (*buf++ != ':')
			;
		for (i = 0; i < 10; i++, buf++) {
			if (*buf == ':')
				break;
			res[i] = *buf;

		}
		buf++;
		bus = str_to_hex(res);
		memset(res, 0, 10);

		for (i = 0; i < 10; i++, buf++) {
			if (*buf == '.')
				break;
			res[i] = *buf;

		}
		buf++;
		slot = str_to_hex(res);
		func = str_to_hex(buf);
		idx_dev = get_dev_idx_bsf(bus, slot, func);

		if (idx_dev != -1) {
		if (idx_dev == -1)
			continue;

			bpctl_dev_arr[idx_dev].ifindex = ifindex;
		bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
		bpctl_dev_arr[idx_dev].ndev = dev;

		}

	}
	/* rtnl_unlock();     */
	/* rcu_read_unlock(); */

}

static long device_ioctl(struct file *file,	/* see include/linux/fs.h */