分类: LINUX
2005-11-21 20:15:13
在drivers/usb/usb.c文件中
其中有两个链表;一个是USB驱动的链表,一个是USB总线的链表。链表头声明为:
LIST_HEAD(usb_driver_list);
LIST_HEAD(usb_bus_list);
其中LIST_HEAD是声明在include/linux/list.h文件中的。
#define LIST_HEAD(name)
struct list_head name = LIST_HEAD_INIT(name)
结构struct list_head 定义如下:
typedef struct list_head {
struct list_head *next, *prev;
} list_t;
而LIST_HEAD_INIT是一个初始化的宏,作用把链表头的两个成员都指向自己。
#define LIST_HEAD_INIT(name) { &(name), &(name) }
1。注册驱动到USB驱动链表中。
该函数把新的驱动添加到驱动链表中,当然usb_driver_list这个链表是连接了struct usb_driver的一个成员 driver_list.
int usb_register(struct usb_driver *new_driver)
{
/* Add it to the list of known drivers */
list_add_tail(&new_driver->driver_list, &usb_driver_list);
return 0;
}
函数 void list_add_tail(struct list_head *new, struct list_head *head)
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
初始化链表头时候的状态:
usb_driver_list<-----usb_driver_list------>usb_driver_list
插入一个新的list_head后,结构变为:
usb_driver_list<-----new<------usb_driver_list------>usb_driver_list
在usb_driver_list和usb_driver_list的prev指向的list_head之前插入了一个新的结构。
2.从USB驱动链表中取得usb_driver结构
从链表中查找每一个驱动,在usb_driver_list的下一个list_head 才是真的struct usb_driver的数据成员,所以tmp=usb_driver_list.next;
即是从下一个开始寻找驱动,为什么tmp!=&usb_driver_list呢,可知道在usb_driver_list初始化为该链表头的时候,他的两个成员都是指向
它自己吗.
static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum)
{
struct list_head *tmp;
struct usb_driver *driver;
for (tmp = usb_driver_list.next; tmp != &usb_driver_list;)
{
driver = list_entry(tmp, struct usb_driver, driver_list);
tmp = tmp->next;
}
}
3。从USB总线结构链表中取得struct usb_bus 结构的总线数据结构。
在usb_bus_list的下一个list_head 才是真的struct usb_bus的数据成员,所以tmp=usb_bus_list.next即是从下一个开始寻找总线,
为什么tmp!=&usb_bus_list呢,可知道在usb_bus_list初始化为该链表头的时候,他的两个成员都是指向它自己吗,
void usb_scan_devices(void)
{
struct list_head *tmp;
tmp = usb_bus_list.next;
while (tmp != &usb_bus_list) {
struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list); //找到了一条总线
tmp = tmp->next;
}
}
找到tmp这个指针的地址,然后通过list_entry这个宏找到bus_list这个struct list_head 类型的成员变量,是结构struct usb_bus里面
的,所以我们通过入口取得一个整个的结构.
如果想对某种类型创建链表,就把一个list_head类型的变量嵌入到该类型中,用list_head中的成员和相对应的处理函数来对链表进行遍
历。如果想得到相应的结构的指针,使用list_entry可以算出来。
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member)
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))