ethtool: Split ethtool_get_eeprom() to allow for additional EEPROM accessors
authorBen Hutchings <bhutchings@solarflare.com>
Thu, 12 Apr 2012 00:42:12 +0000 (00:42 +0000)
committerBen Hutchings <bhutchings@solarflare.com>
Thu, 10 May 2012 01:22:17 +0000 (02:22 +0100)
We want to support reading module (SFP+, XFP, ...) EEPROMs as well as
NIC EEPROMs.  They will need a different command number and driver
operation, but the structure and arguments will be the same and so we
can share most of the code here.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
net/core/ethtool.c

index beacdd93cd8fcd0fff5d95faff1415dd4e7beb67..ca7698fd24d41c3e0d6a76fe187c1247e9caecab 100644 (file)
@@ -751,18 +751,17 @@ static int ethtool_get_link(struct net_device *dev, char __user *useraddr)
        return 0;
 }
 
-static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
+static int ethtool_get_any_eeprom(struct net_device *dev, void __user *useraddr,
+                                 int (*getter)(struct net_device *,
+                                               struct ethtool_eeprom *, u8 *),
+                                 u32 total_len)
 {
        struct ethtool_eeprom eeprom;
-       const struct ethtool_ops *ops = dev->ethtool_ops;
        void __user *userbuf = useraddr + sizeof(eeprom);
        u32 bytes_remaining;
        u8 *data;
        int ret = 0;
 
-       if (!ops->get_eeprom || !ops->get_eeprom_len)
-               return -EOPNOTSUPP;
-
        if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
                return -EFAULT;
 
@@ -771,7 +770,7 @@ static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
                return -EINVAL;
 
        /* Check for exceeding total eeprom len */
-       if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev))
+       if (eeprom.offset + eeprom.len > total_len)
                return -EINVAL;
 
        data = kmalloc(PAGE_SIZE, GFP_USER);
@@ -782,7 +781,7 @@ static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
        while (bytes_remaining > 0) {
                eeprom.len = min(bytes_remaining, (u32)PAGE_SIZE);
 
-               ret = ops->get_eeprom(dev, &eeprom, data);
+               ret = getter(dev, &eeprom, data);
                if (ret)
                        break;
                if (copy_to_user(userbuf, data, eeprom.len)) {
@@ -803,6 +802,17 @@ static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
        return ret;
 }
 
+static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
+{
+       const struct ethtool_ops *ops = dev->ethtool_ops;
+
+       if (!ops->get_eeprom || !ops->get_eeprom_len)
+               return -EOPNOTSUPP;
+
+       return ethtool_get_any_eeprom(dev, useraddr, ops->get_eeprom,
+                                     ops->get_eeprom_len(dev));
+}
+
 static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr)
 {
        struct ethtool_eeprom eeprom;