cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

devres.c (2250B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * This file contains all networking devres helpers.
      4 */
      5
      6#include <linux/device.h>
      7#include <linux/etherdevice.h>
      8#include <linux/netdevice.h>
      9
     10struct net_device_devres {
     11	struct net_device *ndev;
     12};
     13
     14static void devm_free_netdev(struct device *dev, void *this)
     15{
     16	struct net_device_devres *res = this;
     17
     18	free_netdev(res->ndev);
     19}
     20
     21struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
     22					   unsigned int txqs, unsigned int rxqs)
     23{
     24	struct net_device_devres *dr;
     25
     26	dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL);
     27	if (!dr)
     28		return NULL;
     29
     30	dr->ndev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
     31	if (!dr->ndev) {
     32		devres_free(dr);
     33		return NULL;
     34	}
     35
     36	devres_add(dev, dr);
     37
     38	return dr->ndev;
     39}
     40EXPORT_SYMBOL(devm_alloc_etherdev_mqs);
     41
     42static void devm_unregister_netdev(struct device *dev, void *this)
     43{
     44	struct net_device_devres *res = this;
     45
     46	unregister_netdev(res->ndev);
     47}
     48
     49static int netdev_devres_match(struct device *dev, void *this, void *match_data)
     50{
     51	struct net_device_devres *res = this;
     52	struct net_device *ndev = match_data;
     53
     54	return ndev == res->ndev;
     55}
     56
     57/**
     58 *	devm_register_netdev - resource managed variant of register_netdev()
     59 *	@dev: managing device for this netdev - usually the parent device
     60 *	@ndev: device to register
     61 *
     62 *	This is a devres variant of register_netdev() for which the unregister
     63 *	function will be called automatically when the managing device is
     64 *	detached. Note: the net_device used must also be resource managed by
     65 *	the same struct device.
     66 */
     67int devm_register_netdev(struct device *dev, struct net_device *ndev)
     68{
     69	struct net_device_devres *dr;
     70	int ret;
     71
     72	/* struct net_device must itself be managed. For now a managed netdev
     73	 * can only be allocated by devm_alloc_etherdev_mqs() so the check is
     74	 * straightforward.
     75	 */
     76	if (WARN_ON(!devres_find(dev, devm_free_netdev,
     77				 netdev_devres_match, ndev)))
     78		return -EINVAL;
     79
     80	dr = devres_alloc(devm_unregister_netdev, sizeof(*dr), GFP_KERNEL);
     81	if (!dr)
     82		return -ENOMEM;
     83
     84	ret = register_netdev(ndev);
     85	if (ret) {
     86		devres_free(dr);
     87		return ret;
     88	}
     89
     90	dr->ndev = ndev;
     91	devres_add(ndev->dev.parent, dr);
     92
     93	return 0;
     94}
     95EXPORT_SYMBOL(devm_register_netdev);