mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	Correct a grammatical error. Signed-off-by: gushengxian <gushengxian@yulong.com> Signed-off-by: David S. Miller <davem@davemloft.net>
		
			
				
	
	
		
			95 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
						|
/*
 | 
						|
 * This file contains all networking devres helpers.
 | 
						|
 */
 | 
						|
 | 
						|
#include <linux/device.h>
 | 
						|
#include <linux/etherdevice.h>
 | 
						|
#include <linux/netdevice.h>
 | 
						|
 | 
						|
struct net_device_devres {
 | 
						|
	struct net_device *ndev;
 | 
						|
};
 | 
						|
 | 
						|
static void devm_free_netdev(struct device *dev, void *this)
 | 
						|
{
 | 
						|
	struct net_device_devres *res = this;
 | 
						|
 | 
						|
	free_netdev(res->ndev);
 | 
						|
}
 | 
						|
 | 
						|
struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
 | 
						|
					   unsigned int txqs, unsigned int rxqs)
 | 
						|
{
 | 
						|
	struct net_device_devres *dr;
 | 
						|
 | 
						|
	dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL);
 | 
						|
	if (!dr)
 | 
						|
		return NULL;
 | 
						|
 | 
						|
	dr->ndev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
 | 
						|
	if (!dr->ndev) {
 | 
						|
		devres_free(dr);
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	devres_add(dev, dr);
 | 
						|
 | 
						|
	return dr->ndev;
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(devm_alloc_etherdev_mqs);
 | 
						|
 | 
						|
static void devm_unregister_netdev(struct device *dev, void *this)
 | 
						|
{
 | 
						|
	struct net_device_devres *res = this;
 | 
						|
 | 
						|
	unregister_netdev(res->ndev);
 | 
						|
}
 | 
						|
 | 
						|
static int netdev_devres_match(struct device *dev, void *this, void *match_data)
 | 
						|
{
 | 
						|
	struct net_device_devres *res = this;
 | 
						|
	struct net_device *ndev = match_data;
 | 
						|
 | 
						|
	return ndev == res->ndev;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 *	devm_register_netdev - resource managed variant of register_netdev()
 | 
						|
 *	@dev: managing device for this netdev - usually the parent device
 | 
						|
 *	@ndev: device to register
 | 
						|
 *
 | 
						|
 *	This is a devres variant of register_netdev() for which the unregister
 | 
						|
 *	function will be called automatically when the managing device is
 | 
						|
 *	detached. Note: the net_device used must also be resource managed by
 | 
						|
 *	the same struct device.
 | 
						|
 */
 | 
						|
int devm_register_netdev(struct device *dev, struct net_device *ndev)
 | 
						|
{
 | 
						|
	struct net_device_devres *dr;
 | 
						|
	int ret;
 | 
						|
 | 
						|
	/* struct net_device must itself be managed. For now a managed netdev
 | 
						|
	 * can only be allocated by devm_alloc_etherdev_mqs() so the check is
 | 
						|
	 * straightforward.
 | 
						|
	 */
 | 
						|
	if (WARN_ON(!devres_find(dev, devm_free_netdev,
 | 
						|
				 netdev_devres_match, ndev)))
 | 
						|
		return -EINVAL;
 | 
						|
 | 
						|
	dr = devres_alloc(devm_unregister_netdev, sizeof(*dr), GFP_KERNEL);
 | 
						|
	if (!dr)
 | 
						|
		return -ENOMEM;
 | 
						|
 | 
						|
	ret = register_netdev(ndev);
 | 
						|
	if (ret) {
 | 
						|
		devres_free(dr);
 | 
						|
		return ret;
 | 
						|
	}
 | 
						|
 | 
						|
	dr->ndev = ndev;
 | 
						|
	devres_add(ndev->dev.parent, dr);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(devm_register_netdev);
 |