status = device_create_file(dev, &dev_attr_direction);//调用sysfs_create_file为一个sys/class/中一个设备目录创建一个属性文件。
int sysfs_create_dir(struct kobject * kobj)//创建目录
int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)//为目录创建一个属性
我们看看gpiolib.c中gpiolib_sysfs_init,gpio文件系统初始化:
##################################################################################################################
static int __init gpiolib_sysfs_init(void)
{
int status;
unsigned long flags;
struct gpio_chip *chip;
status = class_register(&gpio_class);//注册类,在/sys/class创建目录。
if (status < 0)
return status;
/* Scan and register the gpio_chips which registered very
* early (e.g. before the class_register above was called).
*
* We run before arch_initcall() so chip->dev nodes can have
* registered, and so arch_initcall() can always gpio_export().
*/
spin_lock_irqsave(&gpio_lock, flags);
list_for_each_entry(chip, &gpio_chips, list) {//在gpio驱动注册的时候,有注册gpio_chip(包含多个gpio口),保存在gpio_chips,这里就是对每组gpio进行sys目录创建。
if (!chip || chip->exported)
continue;
//chip是一组gpio控制。
spin_unlock_irqrestore(&gpio_lock, flags);
status = gpiochip_export(chip);//把gpiochip导出来,意思就是用户可见,看下面函数知道,在/sys/class和/sys/devices显示出来。
spin_lock_irqsave(&gpio_lock, flags);
}
spin_unlock_irqrestore(&gpio_lock, flags);
return status;
}
static int gpiochip_export(struct gpio_chip *chip)
{
int status;
struct device *dev;
/* Many systems register gpio chips for SOC support very early,
* before driver model support is available. In those cases we
* export this later, in gpiolib_sysfs_init() ... here we just
* verify that _some_ field of gpio_class got initialized.
*/
if (!gpio_class.p)
return 0;
/* use chip->base for the ID; it‘s already known to be unique */
mutex_lock(&sysfs_lock);
dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip,
"gpiochip%d", chip->base);//创建/sys/class/gpio/gpiochipx(链接文件)和/sys/devices/virtual/gpio/gpiochipx
if (!IS_ERR(dev)) {//创建成功
status = sysfs_create_group(&dev->kobj,
&gpiochip_attr_group);//对/sys/devices/virtual/gpio/gpiochipx/目录创建属性文件。
} else
status = PTR_ERR(dev);
chip->exported = (status == 0);
mutex_unlock(&sysfs_lock);
if (status) {//失败
unsigned long flags;
unsigned gpio;
int register_netdevice_notifier(struct notifier_block *nb)
err = raw_notifier_chain_register(&netdev_chain, nb);
向netdev_chain通知链注册一个通知块nb
int unregister_netdevice_notifier(struct notifier_block *nb)
err = raw_notifier_chain_unregister(&netdev_chain, nb);
注销一个通知块。
int call_netdevice_notifiers(unsigned long val, struct net_device *dev)
{
ASSERT_RTNL();
return raw_notifier_call_chain(&netdev_chain, val, dev);
}
这个就是向通知链发送事件。
网络设备事件通知:netdevice.h
#define NETDEV_UP 0x0001 /* For now you can‘t veto a device up/down */
#define NETDEV_DOWN 0x0002
#define NETDEV_REBOOT 0x0003 /* Tell a protocol stack a network interface
........
usb通知链表头为usb_notifier_list
在/drivers/usb/core/Notify.c文件中,有四个函数()对usb_notifier_list中发送通知,这四个函数如下:
usb_notify_add_device //有设备添加
usb_notify_remove_device //有设备移除
usb_notify_add_bus //总线添加
usb_notify_remove_bus //总线移除
##################################################################################################################
##################################################################################################################
##################################################################################################################
udev:是一个应用层源码包。
kobject_uevent(&drv->p->kobj, KOBJ_ADD);通知udev
##################################################################################################################
##################################################################################################################
##################################################################################################################
lsusb:命令,查看系统usb设备
Bus 003 Device 005: ID 046d:c31c Logitech, Inc. Keyboard K120
Bus 003 Device 004: ID 1bcf:2c55 Sunplus Innovation Technology Inc.
Bus 003 Device 003: ID 093a:2510 Pixart Imaging, Inc. Optical Mouse
Bus 003 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
Bus 003 Device 006: ID 8087:07da Intel Corp.
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
bus表示总线号(系统有多个usb总线),Device表示设备编号,001表示root hub,002串口:表示对新添的设备进行编号(比如003是鼠标,我拔掉鼠标,然后再插上为007)。
ID:usb_device_descriptor.idVendor和usb_device_descriptor.idProduct从设备读取(厂家设定)。