⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dev.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
 *	dev_get	-	test if a device exists *	@name:	name to test for * *	Test if a name exists. Returns true if the name is found. In order *	to be sure the name is not allocated or removed during the test the *	caller must hold the rtnl semaphore. * *	This function exists only for back compatibility with older *	drivers. */int __dev_get(const char *name){	struct net_device *dev;	read_lock(&dev_base_lock);	dev = __dev_get_by_name(name);	read_unlock(&dev_base_lock);	return dev != NULL;}/** *	__dev_get_by_index - find a device by its ifindex *	@ifindex: index of device * *	Search for an interface by index. Returns %NULL if the device *	is not found or a pointer to the device. The device has not *	had its reference counter increased so the caller must be careful *	about locking. The caller must hold either the RTNL semaphore *	or @dev_base_lock. */struct net_device *__dev_get_by_index(int ifindex){	struct hlist_node *p;	hlist_for_each(p, dev_index_hash(ifindex)) {		struct net_device *dev			= hlist_entry(p, struct net_device, index_hlist);		if (dev->ifindex == ifindex)			return dev;	}	return NULL;}/** *	dev_get_by_index - find a device by its ifindex *	@ifindex: index of device * *	Search for an interface by index. Returns NULL if the device *	is not found or a pointer to the device. The device returned has *	had a reference added and the pointer is safe until the user calls *	dev_put to indicate they have finished with it. */struct net_device *dev_get_by_index(int ifindex){	struct net_device *dev;	read_lock(&dev_base_lock);	dev = __dev_get_by_index(ifindex);	if (dev)		dev_hold(dev);	read_unlock(&dev_base_lock);	return dev;}/** *	dev_getbyhwaddr - find a device by its hardware address *	@type: media type of device *	@ha: hardware address * *	Search for an interface by MAC address. Returns NULL if the device *	is not found or a pointer to the device. The caller must hold the *	rtnl semaphore. The returned device has not had its ref count increased *	and the caller must therefore be careful about locking * *	BUGS: *	If the API was consistent this would be __dev_get_by_hwaddr */struct net_device *dev_getbyhwaddr(unsigned short type, char *ha){	struct net_device *dev;	ASSERT_RTNL();	for (dev = dev_base; dev; dev = dev->next)		if (dev->type == type &&		    !memcmp(dev->dev_addr, ha, dev->addr_len))			break;	return dev;}struct net_device *__dev_getfirstbyhwtype(unsigned short type){	struct net_device *dev;	for (dev = dev_base; dev; dev = dev->next)		if (dev->type == type)			break;	return dev;}EXPORT_SYMBOL(__dev_getfirstbyhwtype);struct net_device *dev_getfirstbyhwtype(unsigned short type){	struct net_device *dev;	rtnl_lock();	dev = __dev_getfirstbyhwtype(type);	if (dev)		dev_hold(dev);	rtnl_unlock();	return dev;}EXPORT_SYMBOL(dev_getfirstbyhwtype);/** *	dev_get_by_flags - find any device with given flags *	@if_flags: IFF_* values *	@mask: bitmask of bits in if_flags to check * *	Search for any interface with the given flags. Returns NULL if a device *	is not found or a pointer to the device. The device returned has  *	had a reference added and the pointer is safe until the user calls *	dev_put to indicate they have finished with it. */struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mask){	struct net_device *dev;	read_lock(&dev_base_lock);	dev = __dev_get_by_flags(if_flags, mask);	if (dev)		dev_hold(dev);	read_unlock(&dev_base_lock);	return dev;}/** *	__dev_get_by_flags - find any device with given flags *	@if_flags: IFF_* values *	@mask: bitmask of bits in if_flags to check * *	Search for any interface with the given flags. Returns NULL if a device *	is not found or a pointer to the device. The caller must hold either *	the RTNL semaphore or @dev_base_lock. */struct net_device *__dev_get_by_flags(unsigned short if_flags, unsigned short mask){	struct net_device *dev;	for (dev = dev_base; dev != NULL; dev = dev->next) {		if (((dev->flags ^ if_flags) & mask) == 0)			return dev;	}	return NULL;}/** *	dev_valid_name - check if name is okay for network device *	@name: name string * *	Network device names need to be valid file names to *	to allow sysfs to work */int dev_valid_name(const char *name){	return !(*name == '\0' 		 || !strcmp(name, ".")		 || !strcmp(name, "..")		 || strchr(name, '/'));}/** *	dev_alloc_name - allocate a name for a device *	@dev: device *	@name: name format string * *	Passed a format string - eg "lt%d" it will try and find a suitable *	id. Not efficient for many devices, not called a lot. The caller *	must hold the dev_base or rtnl lock while allocating the name and *	adding the device in order to avoid duplicates. Returns the number *	of the unit assigned or a negative errno code. */int dev_alloc_name(struct net_device *dev, const char *name){	int i = 0;	char buf[IFNAMSIZ];	const char *p;	const int max_netdevices = 8*PAGE_SIZE;	long *inuse;	struct net_device *d;	p = strnchr(name, IFNAMSIZ-1, '%');	if (p) {		/*		 * Verify the string as this thing may have come from		 * the user.  There must be either one "%d" and no other "%"		 * characters.		 */		if (p[1] != 'd' || strchr(p + 2, '%'))			return -EINVAL;		/* Use one page as a bit array of possible slots */		inuse = (long *) get_zeroed_page(GFP_ATOMIC);		if (!inuse)			return -ENOMEM;		for (d = dev_base; d; d = d->next) {			if (!sscanf(d->name, name, &i))				continue;			if (i < 0 || i >= max_netdevices)				continue;			/*  avoid cases where sscanf is not exact inverse of printf */			snprintf(buf, sizeof(buf), name, i);			if (!strncmp(buf, d->name, IFNAMSIZ))				set_bit(i, inuse);		}		i = find_first_zero_bit(inuse, max_netdevices);		free_page((unsigned long) inuse);	}	snprintf(buf, sizeof(buf), name, i);	if (!__dev_get_by_name(buf)) {		strlcpy(dev->name, buf, IFNAMSIZ);		return i;	}	/* It is possible to run out of possible slots	 * when the name is long and there isn't enough space left	 * for the digits, or if all bits are used.	 */	return -ENFILE;}/** *	dev_change_name - change name of a device *	@dev: device *	@newname: name (or format string) must be at least IFNAMSIZ * *	Change name of a device, can pass format strings "eth%d". *	for wildcarding. */int dev_change_name(struct net_device *dev, char *newname){	int err = 0;	ASSERT_RTNL();	if (dev->flags & IFF_UP)		return -EBUSY;	if (!dev_valid_name(newname))		return -EINVAL;	if (strchr(newname, '%')) {		err = dev_alloc_name(dev, newname);		if (err < 0)			return err;		strcpy(newname, dev->name);	}	else if (__dev_get_by_name(newname))		return -EEXIST;	else		strlcpy(dev->name, newname, IFNAMSIZ);	err = class_device_rename(&dev->class_dev, dev->name);	if (!err) {		hlist_del(&dev->name_hlist);		hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));		notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);	}	return err;}/** *	netdev_state_change - device changes state *	@dev: device to cause notification * *	Called to indicate a device has changed state. This function calls *	the notifier chains for netdev_chain and sends a NEWLINK message *	to the routing socket. */void netdev_state_change(struct net_device *dev){	if (dev->flags & IFF_UP) {		notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev);		rtmsg_ifinfo(RTM_NEWLINK, dev, 0);	}}/** *	dev_load 	- load a network module *	@name: name of interface * *	If a network interface is not present and the process has suitable *	privileges this function loads the module. If module loading is not *	available in this kernel then it becomes a nop. */void dev_load(const char *name){	struct net_device *dev;  	read_lock(&dev_base_lock);	dev = __dev_get_by_name(name);	read_unlock(&dev_base_lock);	if (!dev && capable(CAP_SYS_MODULE))		request_module("%s", name);}static int default_rebuild_header(struct sk_buff *skb){	printk(KERN_DEBUG "%s: default_rebuild_header called -- BUG!\n",	       skb->dev ? skb->dev->name : "NULL!!!");	kfree_skb(skb);	return 1;}/** *	dev_open	- prepare an interface for use. *	@dev:	device to open * *	Takes a device from down to up state. The device's private open *	function is invoked and then the multicast lists are loaded. Finally *	the device is moved into the up state and a %NETDEV_UP message is *	sent to the netdev notifier chain. * *	Calling this function on an active interface is a nop. On a failure *	a negative errno code is returned. */int dev_open(struct net_device *dev){	int ret = 0;	/*	 *	Is it already up?	 */	if (dev->flags & IFF_UP)		return 0;	/*	 *	Is it even present?	 */	if (!netif_device_present(dev))		return -ENODEV;	/*	 *	Call device private open method	 */	set_bit(__LINK_STATE_START, &dev->state);	if (dev->open) {		ret = dev->open(dev);		if (ret)			clear_bit(__LINK_STATE_START, &dev->state);	} 	/*	 *	If it went open OK then:	 */	if (!ret) {		/*		 *	Set the flags.		 */		dev->flags |= IFF_UP;		/*		 *	Initialize multicasting status		 */		dev_mc_upload(dev);		/*		 *	Wakeup transmit queue engine		 */		dev_activate(dev);		/*		 *	... and announce new interface.		 */		notifier_call_chain(&netdev_chain, NETDEV_UP, dev);	}	return ret;}/** *	dev_close - shutdown an interface. *	@dev: device to shutdown * *	This function moves an active device into down state. A *	%NETDEV_GOING_DOWN is sent to the netdev notifier chain. The device *	is then deactivated and finally a %NETDEV_DOWN is sent to the notifier *	chain. */int dev_close(struct net_device *dev){	if (!(dev->flags & IFF_UP))		return 0;	/*	 *	Tell people we are going down, so that they can	 *	prepare to death, when device is still operating.	 */	notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev);	dev_deactivate(dev);	clear_bit(__LINK_STATE_START, &dev->state);	/* Synchronize to scheduled poll. We cannot touch poll list,	 * it can be even on different cpu. So just clear netif_running(),	 * and wait when poll really will happen. Actually, the best place	 * for this is inside dev->stop() after device stopped its irq	 * engine, but this requires more changes in devices. */	smp_mb__after_clear_bit(); /* Commit netif_running(). */	while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) {		/* No hurry. */		current->state = TASK_INTERRUPTIBLE;		schedule_timeout(1);	}	/*	 *	Call the device specific close. This cannot fail.	 *	Only if device is UP	 *	 *	We allow it to be called even after a DETACH hot-plug	 *	event.	 */	if (dev->stop)		dev->stop(dev);	/*	 *	Device is now down.	 */	dev->flags &= ~IFF_UP;	/*	 * Tell people we are down	 */	notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);	return 0;}/* *	Device change register/unregister. These are not inline or static *	as we export them to the world. *//** *	register_netdevice_notifier - register a network notifier block *	@nb: notifier * *	Register a notifier to be called when network device events occur. *	The notifier passed is linked into the kernel structures and must *	not be reused until it has been unregistered. A negative errno code *	is returned on a failure. * * 	When registered all registration and up events are replayed *	to the new notifier to allow device to have a race free  *	view of the network device list. */int register_netdevice_notifier(struct notifier_block *nb){	struct net_device *dev;	int err;	rtnl_lock();	err = notifier_chain_register(&netdev_chain, nb);	if (!err) {		for (dev = dev_base; dev; dev = dev->next) {			nb->notifier_call(nb, NETDEV_REGISTER, dev);			if (dev->flags & IFF_UP) 				nb->notifier_call(nb, NETDEV_UP, dev);		}	}	rtnl_unlock();	return err;}/** *	unregister_netdevice_notifier - unregister a network notifier block *	@nb: notifier * *	Unregister a notifier previously registered by *	register_netdevice_notifier(). The notifier is unlinked into the *	kernel structures and may then be reused. A negative errno code *	is returned on a failure. */int unregister_netdevice_notifier(struct notifier_block *nb){	return notifier_chain_unregister(&netdev_chain, nb);}/** *	call_netdevice_notifiers - call all network notifier blocks *      @val: value passed unmodified to notifier function *      @v:   pointer passed unmodified to notifier function * *	Call all network notifier blocks.  Parameters and return value *	are as for notifier_call_chain(). */int call_netdevice_notifiers(unsigned long val, void *v){	return notifier_call_chain(&netdev_chain, val, v);}/* *	Support routine. Sends outgoing frames to any network *	taps currently in use.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -