net/atm/resources.c

Source file repositories/reference/linux-study-clean/net/atm/resources.c

File Facts

System
Linux kernel
Corpus path
net/atm/resources.c
Extension
.c
Size
7814 bytes
Lines
364
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (dev->number == number) {
			atm_dev_hold(dev);
			return dev;
		}
	}
	return NULL;
}

struct atm_dev *atm_dev_lookup(int number)
{
	struct atm_dev *dev;

	mutex_lock(&atm_dev_mutex);
	dev = __atm_dev_lookup(number);
	mutex_unlock(&atm_dev_mutex);
	return dev;
}
EXPORT_SYMBOL(atm_dev_lookup);

struct atm_dev *atm_dev_register(const char *type, struct device *parent,
				 const struct atmdev_ops *ops, int number,
				 unsigned long *flags)
{
	struct atm_dev *dev, *inuse;

	dev = __alloc_atm_dev(type);
	if (!dev) {
		pr_err("no space for dev %s\n", type);
		return NULL;
	}
	mutex_lock(&atm_dev_mutex);
	if (number != -1) {
		inuse = __atm_dev_lookup(number);
		if (inuse) {
			atm_dev_put(inuse);
			mutex_unlock(&atm_dev_mutex);
			kfree(dev);
			return NULL;
		}
		dev->number = number;
	} else {
		dev->number = 0;
		while ((inuse = __atm_dev_lookup(dev->number))) {
			atm_dev_put(inuse);
			dev->number++;
		}
	}

	dev->ops = ops;
	if (flags)
		dev->flags = *flags;
	else
		memset(&dev->flags, 0, sizeof(dev->flags));
	memset(&dev->stats, 0, sizeof(dev->stats));
	refcount_set(&dev->refcnt, 1);

	if (atm_proc_dev_register(dev) < 0) {
		pr_err("atm_proc_dev_register failed for dev %s\n", type);
		mutex_unlock(&atm_dev_mutex);
		kfree(dev);
		return NULL;
	}

	if (atm_register_sysfs(dev, parent) < 0) {
		pr_err("atm_register_sysfs failed for dev %s\n", type);
		atm_proc_dev_deregister(dev);
		goto out_fail;
	}

	list_add_tail(&dev->dev_list, &atm_devs);

out:
	mutex_unlock(&atm_dev_mutex);
	return dev;

out_fail:
	put_device(&dev->class_dev);
	dev = NULL;
	goto out;
}
EXPORT_SYMBOL(atm_dev_register);

void atm_dev_deregister(struct atm_dev *dev)
{
	BUG_ON(test_bit(ATM_DF_REMOVED, &dev->flags));
	set_bit(ATM_DF_REMOVED, &dev->flags);

	/*
	 * if we remove current device from atm_devs list, new device
	 * with same number can appear, such we need deregister proc,

Annotation

Implementation Notes