netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] eth phy: add mdio bus char device interface
@ 2018-06-18  3:32 Wei Li
  2018-06-18  3:32 ` [PATCH 2/2] " Wei Li
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Wei Li @ 2018-06-18  3:32 UTC (permalink / raw)
  To: andrew, f.fainelli; +Cc: netdev

Add the char device interface of mdio bus, like what i2c-dev or spidev do.
They make it possible for user-space programs to access the bus directly.

Signed-off-by: Wei Li <liwei1412@163.com>
---
 drivers/net/phy/Kconfig    |  10 ++
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/mdio-dev.c | 376 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mdio-dev.h   |  28 ++++
 4 files changed, 415 insertions(+)
 create mode 100644 drivers/net/phy/mdio-dev.c
 create mode 100644 include/linux/mdio-dev.h

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index bdfbabb..cd688c5 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -158,6 +158,16 @@ config MDIO_XGENE
 	  This module provides a driver for the MDIO busses found in the
 	  APM X-Gene SoC's.
 
+config MDIO_CHARDEV
+	tristate "MDIO device interface"
+	help
+	  Say Y here to use mdio-* device files, usually found in the /dev
+	  directory on your system.  They make it possible to have user-space
+	  programs use the MDIO bus.
+
+	  This support is also available as a module.  If so, the module
+	  will be called mdio-dev.
+
 endif
 
 config PHYLINK
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 01acbcb..a0566f8 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
 obj-$(CONFIG_MDIO_SUN4I)	+= mdio-sun4i.o
 obj-$(CONFIG_MDIO_THUNDER)	+= mdio-thunder.o
 obj-$(CONFIG_MDIO_XGENE)	+= mdio-xgene.o
+obj-$(CONFIG_MDIO_CHARDEV)	+= mdio-dev.o
 
 obj-$(CONFIG_SFP)		+= sfp.o
 sfp-obj-$(CONFIG_SFP)		+= sfp-bus.o
diff --git a/drivers/net/phy/mdio-dev.c b/drivers/net/phy/mdio-dev.c
new file mode 100644
index 0000000..61487d2
--- /dev/null
+++ b/drivers/net/phy/mdio-dev.c
@@ -0,0 +1,376 @@
+/*
+ * mdio-dev.c - mdio-bus driver, char device interface
+ *
+ * Copyright (C) 2018 Wei Li <liwei1412@163.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/mdio-dev.h>
+#include <linux/mdio.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/slab.h>
+#include <linux/phy.h>
+
+/*
+ * An mdio_dev represents a mii_bus.  It's coupled
+ * with a character special file which is accessed by user mode drivers.
+ *
+ * The list of mdio_dev structures is parallel to the mii_bus lists
+ * maintained by the driver model, and is updated using bus notifications.
+ */
+struct mdio_dev {
+	struct list_head list;
+	struct mii_bus *bus;
+	int nr;
+	struct device *dev;
+	struct cdev cdev;
+};
+
+static DEFINE_MUTEX(mdio_dev_lock);
+static DEFINE_IDR(mdio_dev_idr);
+static LIST_HEAD(mdio_dev_list);
+static DEFINE_SPINLOCK(mdio_dev_list_lock);
+
+static struct mdio_dev *mdio_dev_get_by_bus(struct mii_bus *bus)
+{
+	struct mdio_dev *mdio_dev;
+
+	if (!bus)
+		return NULL;
+
+	spin_lock(&mdio_dev_list_lock);
+	list_for_each_entry(mdio_dev, &mdio_dev_list, list) {
+		if (mdio_dev->bus == bus)
+			goto found;
+	}
+	mdio_dev = NULL;
+found:
+	spin_unlock(&mdio_dev_list_lock);
+	return mdio_dev;
+}
+
+static int alloc_mdio_dev_id(struct mdio_dev *mdio_dev)
+{
+	int id;
+
+	mutex_lock(&mdio_dev_lock);
+	id = idr_alloc(&mdio_dev_idr, mdio_dev, 0, MDIO_MINORS, GFP_KERNEL);
+	mutex_unlock(&mdio_dev_lock);
+	if (WARN(id < 0, "couldn't get idr"))
+		return id == -ENOSPC ? -EBUSY : id;
+
+	mdio_dev->nr = id;
+	return 0;
+}
+
+static void free_mdio_dev_id(struct mdio_dev *mdio_dev)
+{
+	mutex_lock(&mdio_dev_lock);
+	idr_remove(&mdio_dev_idr, mdio_dev->nr);
+	mutex_unlock(&mdio_dev_lock);
+	mdio_dev->nr = -1;
+}
+
+static struct mii_bus *mdiodev_get_bus(int nr)
+{
+	struct mdio_dev *found;
+
+	mutex_lock(&mdio_dev_lock);
+	found = idr_find(&mdio_dev_idr, nr);
+	if (!found)
+		goto exit;
+
+	if (try_module_get(found->bus->owner))
+		get_device(&found->bus->dev);
+	else
+		found = NULL;
+
+exit:
+	mutex_unlock(&mdio_dev_lock);
+	return found ? found->bus : NULL;
+}
+
+static void mdiodev_put_bus(struct mii_bus *bus)
+{
+	if (!bus)
+		return;
+
+	put_device(&bus->dev);
+	module_put(bus->owner);
+}
+
+static struct mdio_dev *get_free_mdio_dev(struct mii_bus *bus)
+{
+	struct mdio_dev *mdio_dev;
+
+	mdio_dev = kzalloc(sizeof(*mdio_dev), GFP_KERNEL);
+	if (!mdio_dev)
+		return ERR_PTR(-ENOMEM);
+	mdio_dev->bus = bus;
+
+	if (alloc_mdio_dev_id(mdio_dev)) {
+		printk(KERN_ERR "mdio-dev: Out of device minors\n");
+		kfree(mdio_dev);
+		return ERR_PTR(-ENODEV);
+	}
+
+	spin_lock(&mdio_dev_list_lock);
+	list_add_tail(&mdio_dev->list, &mdio_dev_list);
+	spin_unlock(&mdio_dev_list_lock);
+	return mdio_dev;
+}
+
+static void put_mdio_dev(struct mdio_dev *mdio_dev)
+{
+	spin_lock(&mdio_dev_list_lock);
+	list_del(&mdio_dev->list);
+	spin_unlock(&mdio_dev_list_lock);
+	free_mdio_dev_id(mdio_dev);
+	kfree(mdio_dev);
+}
+
+static ssize_t name_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct mii_bus *bus = mdiodev_get_bus(MINOR(dev->devt));
+
+	if (!bus)
+		return -ENODEV;
+	return sprintf(buf, "%s\n", bus->name);
+}
+static DEVICE_ATTR_RO(name);
+
+static struct attribute *mdio_attrs[] = {
+	&dev_attr_name.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(mdio);
+
+/*-------------------------------------------------------------------------*/
+
+static long mdiodev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct mii_bus *bus = file->private_data;
+	struct mii_ioctl_data data;
+	int res;
+
+	dev_dbg(&bus->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n", cmd, arg);
+
+	switch (cmd) {
+	case SIOCSMIIREG:
+		if (copy_from_user(&data,
+					(struct mii_ioctl_data __user *)arg, sizeof(data)))
+			return -EFAULT;
+
+		res = mdiobus_write(bus, data.phy_id, data.reg_num, data.val_in);
+		if (res < 0)
+			return -EIO;
+		return 0;
+
+	case SIOCGMIIREG:
+		if (copy_from_user(&data,
+					(struct mii_ioctl_data __user *)arg, sizeof(data)))
+			return -EFAULT;
+
+		res = mdiobus_read(bus, data.phy_id, data.reg_num);
+		if (res < 0)
+			return -EIO;
+
+		data.val_out = res;
+		if (copy_to_user((struct mii_ioctl_data __user *)arg,
+					&data, sizeof(data)))
+			return -EFAULT;
+		return 0;
+
+	default:
+		return -ENOTTY;
+	}
+	return 0;
+}
+
+static int mdiodev_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor = iminor(inode);
+	struct mii_bus *bus;
+
+	bus = mdiodev_get_bus(minor);
+	if (!bus)
+		return -ENODEV;
+
+	file->private_data = bus;
+
+	return 0;
+}
+
+static int mdiodev_release(struct inode *inode, struct file *file)
+{
+	struct mii_bus *bus = file->private_data;
+
+	mdiodev_put_bus(bus);
+	file->private_data = NULL;
+
+	return 0;
+}
+
+static const struct file_operations mdiodev_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.unlocked_ioctl	= mdiodev_ioctl,
+	.open		= mdiodev_open,
+	.release	= mdiodev_release,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int mdio_major;
+static struct class *mdio_dev_class;
+
+static int mdiodev_attach_bus(struct device *dev, void *dummy)
+{
+	struct mii_bus *bus;
+	struct mdio_dev *mdio_dev;
+	int res;
+
+	if (dev->class != &mdio_bus_class)
+		return 0;
+	bus = to_mii_bus(dev);
+
+	mdio_dev = get_free_mdio_dev(bus);
+	if (IS_ERR(mdio_dev))
+		return PTR_ERR(mdio_dev);
+
+	cdev_init(&mdio_dev->cdev, &mdiodev_fops);
+	mdio_dev->cdev.owner = THIS_MODULE;
+	res = cdev_add(&mdio_dev->cdev, MKDEV(mdio_major, mdio_dev->nr), 1);
+	if (res)
+		goto error_cdev;
+
+	/* register this mdio device with the driver core */
+	mdio_dev->dev = device_create(mdio_dev_class, &bus->dev,
+						MKDEV(mdio_major, mdio_dev->nr), NULL,
+						"mdio-%d", mdio_dev->nr);
+	if (IS_ERR(mdio_dev->dev)) {
+		res = PTR_ERR(mdio_dev->dev);
+		goto error;
+	}
+
+	pr_debug("mdio-dev: bus [%s] registered as minor %d\n",
+			bus->name, mdio_dev->nr);
+	return 0;
+error:
+	cdev_del(&mdio_dev->cdev);
+error_cdev:
+	put_mdio_dev(mdio_dev);
+	return res;
+}
+
+static int mdiodev_detach_bus(struct device *dev, void *dummy)
+{
+	struct mii_bus *bus;
+	struct mdio_dev *mdio_dev;
+
+	if (dev->class != &mdio_bus_class)
+		return 0;
+	bus = to_mii_bus(dev);
+
+	mdio_dev = mdio_dev_get_by_bus(bus);
+	if (!mdio_dev) /* attach_bus must have failed */
+		return 0;
+
+	cdev_del(&mdio_dev->cdev);
+	device_destroy(mdio_dev_class, MKDEV(mdio_major, mdio_dev->nr));
+	put_mdio_dev(mdio_dev);
+
+	pr_debug("mdio-dev: bus [%s] unregistered\n", bus->name);
+	return 0;
+}
+
+static int mdiodev_notifier_call(struct notifier_block *nb, unsigned long action,
+			void *data)
+{
+	struct device *dev = data;
+
+	switch (action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		return mdiodev_attach_bus(dev, NULL);
+	case BUS_NOTIFY_DEL_DEVICE:
+		return mdiodev_detach_bus(dev, NULL);
+	}
+
+	return 0;
+}
+
+static struct notifier_block mdiodev_notifier = {
+	.notifier_call = mdiodev_notifier_call,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init mdio_dev_init(void)
+{
+	int res;
+	dev_t devid;
+
+	printk(KERN_INFO "mdio /dev entries driver\n");
+
+	res = alloc_chrdev_region(&devid, 0, MDIO_MINORS, "mdio");
+	if (res)
+		goto out;
+
+	mdio_major = MAJOR(devid);
+	mdio_dev_class = class_create(THIS_MODULE, "mdio-dev");
+	if (IS_ERR(mdio_dev_class)) {
+		res = PTR_ERR(mdio_dev_class);
+		goto out_unreg_chrdev;
+	}
+	mdio_dev_class->dev_groups = mdio_groups;
+
+	/* Keep track of buses which will be added or removed later */
+	res = mdiobus_register_notifier(&mdiodev_notifier);
+	if (res)
+		goto out_unreg_class;
+
+	/* Bind to already existing buses right away */
+	class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_attach_bus);
+
+	return 0;
+
+out_unreg_class:
+	class_destroy(mdio_dev_class);
+out_unreg_chrdev:
+	unregister_chrdev_region(MKDEV(mdio_major, 0), MDIO_MINORS);
+out:
+	printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);
+	return res;
+}
+
+static void __exit mdio_dev_exit(void)
+{
+	mdiobus_unregister_notifier(&mdiodev_notifier);
+	class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_detach_bus);
+	class_destroy(mdio_dev_class);
+	unregister_chrdev_region(MKDEV(mdio_major, 0), MDIO_MINORS);
+}
+
+MODULE_AUTHOR("Wei Li <liwei1412@163.com>");
+MODULE_DESCRIPTION("MDIO /dev entries driver");
+MODULE_LICENSE("GPL");
+
+module_init(mdio_dev_init);
+module_exit(mdio_dev_exit);
diff --git a/include/linux/mdio-dev.h b/include/linux/mdio-dev.h
new file mode 100644
index 0000000..cc4ed36
--- /dev/null
+++ b/include/linux/mdio-dev.h
@@ -0,0 +1,28 @@
+/*
+ * mdio-dev.h - mdio-bus driver, char device interface
+ *
+ * Copyright (C) 2018 Wei Li <liwei1412@163.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+#ifndef _LINUX_MDIO_DEV_H
+#define _LINUX_MDIO_DEV_H
+
+#include <uapi/linux/mii.h>
+
+#define MDIO_MINORS	MINORMASK
+
+#endif /* _LINUX_MDIO_DEV_H */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] eth phy: add mdio bus char device interface
  2018-06-18  3:32 [PATCH 1/2] eth phy: add mdio bus char device interface Wei Li
@ 2018-06-18  3:32 ` Wei Li
  2018-06-18  6:52   ` kbuild test robot
  2018-06-18  5:22 ` [PATCH 1/2] " kbuild test robot
  2018-06-18  7:25 ` Andrew Lunn
  2 siblings, 1 reply; 5+ messages in thread
From: Wei Li @ 2018-06-18  3:32 UTC (permalink / raw)
  To: andrew, f.fainelli; +Cc: netdev

Add the notifier for the change of mdio bus, since i wanna that a char device
represents a mii_bus not a mdio_device.

Signed-off-by: Wei Li <liwei1412@163.com>
---
 drivers/net/phy/mdio_bus.c | 21 ++++++++++++++++++++-
 include/linux/mdio.h       |  1 +
 include/linux/phy.h        |  2 ++
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 24b5511..3821dc8 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -240,10 +240,25 @@ static void mdiobus_release(struct device *d)
 	kfree(bus);
 }
 
-static struct class mdio_bus_class = {
+struct class mdio_bus_class = {
 	.name		= "mdio_bus",
 	.dev_release	= mdiobus_release,
 };
+EXPORT_SYMBOL_GPL(mdio_bus_class);
+
+static BLOCKING_NOTIFIER_HEAD(mdio_bus_notifier_list);
+
+int mdiobus_register_notifier(struct notifier_block *nb)
+{
+    return blocking_notifier_chain_register(
+				&mdio_bus_notifier_list, nb);
+}
+
+int mdiobus_unregister_notifier(struct notifier_block *nb)
+{
+    return blocking_notifier_chain_unregister(
+				&mdio_bus_notifier_list, nb);
+}
 
 #if IS_ENABLED(CONFIG_OF_MDIO)
 /* Helper function for of_mdio_find_bus */
@@ -418,6 +433,8 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
 	mdiobus_setup_mdiodev_from_board_info(bus, mdiobus_create_device);
 
 	bus->state = MDIOBUS_REGISTERED;
+	blocking_notifier_call_chain(&mdio_bus_notifier_list,
+					BUS_NOTIFY_ADD_DEVICE, &bus->dev);
 	pr_info("%s: probed\n", bus->name);
 	return 0;
 
@@ -446,6 +463,8 @@ void mdiobus_unregister(struct mii_bus *bus)
 	int i;
 
 	BUG_ON(bus->state != MDIOBUS_REGISTERED);
+	blocking_notifier_call_chain(&mdio_bus_notifier_list,
+					BUS_NOTIFY_DEL_DEVICE, &bus->dev);
 	bus->state = MDIOBUS_UNREGISTERED;
 
 	for (i = 0; i < PHY_MAX_ADDR; i++) {
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index 2cfffe5..29ab455 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -79,6 +79,7 @@ void mdio_device_reset(struct mdio_device *mdiodev, int value);
 int mdio_driver_register(struct mdio_driver *drv);
 void mdio_driver_unregister(struct mdio_driver *drv);
 int mdio_device_bus_match(struct device *dev, struct device_driver *drv);
+extern struct class mdio_bus_class;
 
 static inline bool mdio_phy_id_is_c45(int phy_id)
 {
diff --git a/include/linux/phy.h b/include/linux/phy.h
index f0b5870..39f2609 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -246,6 +246,8 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner);
 #define mdiobus_register(bus) __mdiobus_register(bus, THIS_MODULE)
 void mdiobus_unregister(struct mii_bus *bus);
 void mdiobus_free(struct mii_bus *bus);
+int mdiobus_register_notifier(struct notifier_block *nb);
+int mdiobus_unregister_notifier(struct notifier_block *nb);
 struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv);
 static inline struct mii_bus *devm_mdiobus_alloc(struct device *dev)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] eth phy: add mdio bus char device interface
  2018-06-18  3:32 [PATCH 1/2] eth phy: add mdio bus char device interface Wei Li
  2018-06-18  3:32 ` [PATCH 2/2] " Wei Li
@ 2018-06-18  5:22 ` kbuild test robot
  2018-06-18  7:25 ` Andrew Lunn
  2 siblings, 0 replies; 5+ messages in thread
From: kbuild test robot @ 2018-06-18  5:22 UTC (permalink / raw)
  To: Wei Li; +Cc: kbuild-all, andrew, f.fainelli, netdev

[-- Attachment #1: Type: text/plain, Size: 7227 bytes --]

Hi Wei,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/master]
[also build test ERROR on v4.18-rc1 next-20180615]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Wei-Li/eth-phy-add-mdio-bus-char-device-interface/20180618-115206
config: xtensa-allmodconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=xtensa 

Note: the linux-review/Wei-Li/eth-phy-add-mdio-bus-char-device-interface/20180618-115206 HEAD 611497ceadd8527fc1e4aa0eb8936171906118dd builds fine.
      It only hurts bisectibility.

All errors (new ones prefixed by >>):

   drivers/net/phy/mdio-dev.c: In function 'mdiodev_attach_bus':
>> drivers/net/phy/mdio-dev.c:250:21: error: 'mdio_bus_class' undeclared (first use in this function); did you mean 'mdio_dev_class'?
     if (dev->class != &mdio_bus_class)
                        ^~~~~~~~~~~~~~
                        mdio_dev_class
   drivers/net/phy/mdio-dev.c:250:21: note: each undeclared identifier is reported only once for each function it appears in
   drivers/net/phy/mdio-dev.c: In function 'mdiodev_detach_bus':
   drivers/net/phy/mdio-dev.c:288:21: error: 'mdio_bus_class' undeclared (first use in this function); did you mean 'mdio_dev_class'?
     if (dev->class != &mdio_bus_class)
                        ^~~~~~~~~~~~~~
                        mdio_dev_class
   drivers/net/phy/mdio-dev.c: In function 'mdio_dev_init':
>> drivers/net/phy/mdio-dev.c:345:8: error: implicit declaration of function 'mdiobus_register_notifier'; did you mean 'bus_register_notifier'? [-Werror=implicit-function-declaration]
     res = mdiobus_register_notifier(&mdiodev_notifier);
           ^~~~~~~~~~~~~~~~~~~~~~~~~
           bus_register_notifier
   drivers/net/phy/mdio-dev.c:350:25: error: 'mdio_bus_class' undeclared (first use in this function); did you mean 'mdio_dev_class'?
     class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_attach_bus);
                            ^~~~~~~~~~~~~~
                            mdio_dev_class
   drivers/net/phy/mdio-dev.c: In function 'mdio_dev_exit':
>> drivers/net/phy/mdio-dev.c:365:2: error: implicit declaration of function 'mdiobus_unregister_notifier'; did you mean 'bus_unregister_notifier'? [-Werror=implicit-function-declaration]
     mdiobus_unregister_notifier(&mdiodev_notifier);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
     bus_unregister_notifier
   drivers/net/phy/mdio-dev.c:366:25: error: 'mdio_bus_class' undeclared (first use in this function); did you mean 'mdio_dev_class'?
     class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_detach_bus);
                            ^~~~~~~~~~~~~~
                            mdio_dev_class
   cc1: some warnings being treated as errors

vim +250 drivers/net/phy/mdio-dev.c

   243	
   244	static int mdiodev_attach_bus(struct device *dev, void *dummy)
   245	{
   246		struct mii_bus *bus;
   247		struct mdio_dev *mdio_dev;
   248		int res;
   249	
 > 250		if (dev->class != &mdio_bus_class)
   251			return 0;
   252		bus = to_mii_bus(dev);
   253	
   254		mdio_dev = get_free_mdio_dev(bus);
   255		if (IS_ERR(mdio_dev))
   256			return PTR_ERR(mdio_dev);
   257	
   258		cdev_init(&mdio_dev->cdev, &mdiodev_fops);
   259		mdio_dev->cdev.owner = THIS_MODULE;
   260		res = cdev_add(&mdio_dev->cdev, MKDEV(mdio_major, mdio_dev->nr), 1);
   261		if (res)
   262			goto error_cdev;
   263	
   264		/* register this mdio device with the driver core */
   265		mdio_dev->dev = device_create(mdio_dev_class, &bus->dev,
   266							MKDEV(mdio_major, mdio_dev->nr), NULL,
   267							"mdio-%d", mdio_dev->nr);
   268		if (IS_ERR(mdio_dev->dev)) {
   269			res = PTR_ERR(mdio_dev->dev);
   270			goto error;
   271		}
   272	
   273		pr_debug("mdio-dev: bus [%s] registered as minor %d\n",
   274				bus->name, mdio_dev->nr);
   275		return 0;
   276	error:
   277		cdev_del(&mdio_dev->cdev);
   278	error_cdev:
   279		put_mdio_dev(mdio_dev);
   280		return res;
   281	}
   282	
   283	static int mdiodev_detach_bus(struct device *dev, void *dummy)
   284	{
   285		struct mii_bus *bus;
   286		struct mdio_dev *mdio_dev;
   287	
   288		if (dev->class != &mdio_bus_class)
   289			return 0;
   290		bus = to_mii_bus(dev);
   291	
   292		mdio_dev = mdio_dev_get_by_bus(bus);
   293		if (!mdio_dev) /* attach_bus must have failed */
   294			return 0;
   295	
   296		cdev_del(&mdio_dev->cdev);
   297		device_destroy(mdio_dev_class, MKDEV(mdio_major, mdio_dev->nr));
   298		put_mdio_dev(mdio_dev);
   299	
   300		pr_debug("mdio-dev: bus [%s] unregistered\n", bus->name);
   301		return 0;
   302	}
   303	
   304	static int mdiodev_notifier_call(struct notifier_block *nb, unsigned long action,
   305				void *data)
   306	{
   307		struct device *dev = data;
   308	
   309		switch (action) {
   310		case BUS_NOTIFY_ADD_DEVICE:
   311			return mdiodev_attach_bus(dev, NULL);
   312		case BUS_NOTIFY_DEL_DEVICE:
   313			return mdiodev_detach_bus(dev, NULL);
   314		}
   315	
   316		return 0;
   317	}
   318	
   319	static struct notifier_block mdiodev_notifier = {
   320		.notifier_call = mdiodev_notifier_call,
   321	};
   322	
   323	/*-------------------------------------------------------------------------*/
   324	
   325	static int __init mdio_dev_init(void)
   326	{
   327		int res;
   328		dev_t devid;
   329	
   330		printk(KERN_INFO "mdio /dev entries driver\n");
   331	
   332		res = alloc_chrdev_region(&devid, 0, MDIO_MINORS, "mdio");
   333		if (res)
   334			goto out;
   335	
   336		mdio_major = MAJOR(devid);
   337		mdio_dev_class = class_create(THIS_MODULE, "mdio-dev");
   338		if (IS_ERR(mdio_dev_class)) {
   339			res = PTR_ERR(mdio_dev_class);
   340			goto out_unreg_chrdev;
   341		}
   342		mdio_dev_class->dev_groups = mdio_groups;
   343	
   344		/* Keep track of buses which will be added or removed later */
 > 345		res = mdiobus_register_notifier(&mdiodev_notifier);
   346		if (res)
   347			goto out_unreg_class;
   348	
   349		/* Bind to already existing buses right away */
   350		class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_attach_bus);
   351	
   352		return 0;
   353	
   354	out_unreg_class:
   355		class_destroy(mdio_dev_class);
   356	out_unreg_chrdev:
   357		unregister_chrdev_region(MKDEV(mdio_major, 0), MDIO_MINORS);
   358	out:
   359		printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);
   360		return res;
   361	}
   362	
   363	static void __exit mdio_dev_exit(void)
   364	{
 > 365		mdiobus_unregister_notifier(&mdiodev_notifier);
   366		class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_detach_bus);
   367		class_destroy(mdio_dev_class);
   368		unregister_chrdev_region(MKDEV(mdio_major, 0), MDIO_MINORS);
   369	}
   370	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 53907 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] eth phy: add mdio bus char device interface
  2018-06-18  3:32 ` [PATCH 2/2] " Wei Li
@ 2018-06-18  6:52   ` kbuild test robot
  0 siblings, 0 replies; 5+ messages in thread
From: kbuild test robot @ 2018-06-18  6:52 UTC (permalink / raw)
  To: Wei Li; +Cc: kbuild-all, andrew, f.fainelli, netdev

[-- Attachment #1: Type: text/plain, Size: 1237 bytes --]

Hi Wei,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/master]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Wei-Li/eth-phy-add-mdio-bus-char-device-interface/20180618-115206
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=ia64 

All errors (new ones prefixed by >>):

   ERROR: "ia64_delay_loop" [drivers/spi/spi-thunderx.ko] undefined!
   ERROR: "__sw_hweight8" [drivers/net/wireless/mediatek/mt76/mt76.ko] undefined!
>> ERROR: "mdiobus_unregister_notifier" [drivers/net/phy/mdio-dev.ko] undefined!
>> ERROR: "mdiobus_register_notifier" [drivers/net/phy/mdio-dev.ko] undefined!
   ERROR: "ia64_delay_loop" [drivers/net/phy/mdio-cavium.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 50794 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] eth phy: add mdio bus char device interface
  2018-06-18  3:32 [PATCH 1/2] eth phy: add mdio bus char device interface Wei Li
  2018-06-18  3:32 ` [PATCH 2/2] " Wei Li
  2018-06-18  5:22 ` [PATCH 1/2] " kbuild test robot
@ 2018-06-18  7:25 ` Andrew Lunn
  2 siblings, 0 replies; 5+ messages in thread
From: Andrew Lunn @ 2018-06-18  7:25 UTC (permalink / raw)
  To: Wei Li; +Cc: f.fainelli, netdev

1;5202;0cOn Mon, Jun 18, 2018 at 11:32:12AM +0800, Wei Li wrote:
> Add the char device interface of mdio bus, like what i2c-dev or spidev do.
> They make it possible for user-space programs to access the bus directly.
> 


Hi Wei

What is your real use case here? 

What we don't want to do is add an easy to use API to allow vendors to
write user space binary blob propriatary Ethernet switch or PHY
drivers.

Also, it has been agreed that all new API's to the network stack need
to use netlink sockets, not IOCTLs.

The IOCTL interface you provide is very similar to what the stack
already has. Why cannot use you use that?

	Andrew

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-06-18  7:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-18  3:32 [PATCH 1/2] eth phy: add mdio bus char device interface Wei Li
2018-06-18  3:32 ` [PATCH 2/2] " Wei Li
2018-06-18  6:52   ` kbuild test robot
2018-06-18  5:22 ` [PATCH 1/2] " kbuild test robot
2018-06-18  7:25 ` Andrew Lunn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).