staging: silicom: introduce bp_dev_get_idx_bsf() and use it
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Fri, 13 Sep 2013 06:44:31 +0000 (09:44 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Sep 2013 14:47:46 +0000 (07:47 -0700)
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: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/silicom/bpctl_mod.c

index 495272d0134859bf36f080bd7a5c53bc5e0ae708..39dc92a271aba2a1f341a224bd59089fa2ba3870 100644 (file)
@@ -1,11 +1,11 @@
 /******************************************************************************/
 /*                                                                            */
-/* 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 (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) {
-                               memset(&drvinfo, 0, sizeof(drvinfo));
-                               dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
-                       } else
-                               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 (event == NETDEV_REGISTER) {
+               int idx_dev;
 
-                               bpctl_dev_arr[idx_dev].ifindex = ifindex;
-                               bpctl_dev_arr[idx_dev].ndev = dev;
+               if (bp_get_dev_idx_bsf(dev, &idx_dev))
+                       return NOTIFY_DONE;
 
-                               bypass_proc_remove_dev_sd(&bpctl_dev_arr
-                                                         [idx_dev]);
-                               bypass_proc_create_dev_sd(&bpctl_dev_arr
-                                                         [idx_dev]);
+               if (idx_dev == -1)
+                       return NOTIFY_DONE;
 
-                       }
+               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]);
                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
+               if (bp_get_dev_idx_bsf(dev, &idx_dev))
                        continue;
-               if (!strcmp(drvinfo.bus_info, "N/A"))
-                       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) {
-
-                       bpctl_dev_arr[idx_dev].ifindex = ifindex;
-                       bpctl_dev_arr[idx_dev].ndev = dev;
-
-               }
+               if (idx_dev == -1)
+                       continue;
 
+               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 */