网络驱动的接口函数net/ddi.c
先介绍其数据结构:
主要包括:
struct ddi_device {
char *title; /* title of the driver */
char name[DDI_MAXNAME]; /* unit name of the I/O driver */
short int unit; /* unit number of this driver */
short int nunits; /* number of units in driver */
int (*init)(struct ddi_device *); /* initialization func */
int (*handler)(int, ...); /* command handler */
short int major; /* driver major dev number */
short int minor; /* driver minor dev number */
unsigned long flags; /* various flags */
struct ddconf config; /* driver HW setup */
};
struct ddconf {
int ioaddr; /* main I/O (port) address */
int ioaux; /* auxiliary I/O (HD, AST) */
int irq; /* IRQ channel */
int dma; /* DMA channel to use */
unsigned long memsize; /* size of onboard memory */
unsigned long memaddr; /* base address of memory */
};
struct ddi_device devices[] = {
#if CONF_WE8003
{ "WD80x3[EBT]",
"", 0, 1, we8003_init, NULL,
19, 0, DDI_FCHRDEV,
{ 0x280, 0, 15, 0, 32768, 0xD0000 } },
#endif
#if CONF_DP8390
{ "DP8390/WD80x3",
"", 0, 1, dpwd8003_init, NULL,
20, 0, DDI_FCHRDEV,
{ 0, 0, 0, 0, 0, 0, } },
{ "DP8390/NE-x000",
"", 0, 1, dpne2000_init, NULL,
20, 8, DDI_FCHRDEV,
{ 0, 0, 0, 0, 0, 0, } },
{ "DP8390/3C50x",
"", 0, 1, dpec503_init, NULL,
20, 16, DDI_FCHRDEV,
{ 0, 0, 0, 0, 0, 0, } },
#endif
{ NULL,
"", 0, 0, NULL, NULL,
0, 0, 0,
{ 0, 0, 0, 0, 0, 0 } }
};
初始化过程:
系统初始化时会调用ddi_init();
初始化是由ddi_init()开始的,
pro = protocols;
while(pro->name != NULL){
(*pro->init)(pro);
pro++;
}
因为在ddi.h中定义了全局的protocols数组:
struct ddi_proto protocols[] = {
#ifdef CONFIG_UNIX
{ "UNIX", unix_proto_init },
#endif
#ifdef CONFIG_IPX
{ "IPX", ipx_proto_init },
#endif
#ifdef CONFIG_AX25
{ "AX.25", ax25_proto_init },
#endif
#ifdef CONFIG_INET
{ "INET", inet_proto_init },
#endif
{ NULL, NULL }
};
所以以“INET”为例说明其初始化过程:
所做的工作具体为:
1,register_chrdev()也就是将网络设备的设备名和操作函数加入到chrdevs全局数组中
static struct file_operations inet_fops = {
NULL, /* LSEEK */
NULL, /* READ */
NULL, /* WRITE */
NULL, /* READDIR */
NULL, /* SELECT */
inet_fioctl, /* IOCTL */
NULL, /* MMAP */
NULL, /* OPEN */
NULL /* CLOSE */
};
2,sock_register()就是将相对于sock的操作加入到pops中
static struct proto_ops inet_proto_ops = {
AF_INET,
inet_create,
inet_dup,
inet_release,
inet_bind,
inet_connect,
inet_socketpair,
inet_accept,
inet_getname,
inet_read,
inet_write,
inet_select,
inet_ioctl,
inet_listen,
inet_send,
inet_recv,
inet_sendto,
inet_recvfrom,
inet_shutdown,
inet_setsockopt,
inet_getsockopt,
inet_fcntl,
};
3,初始化各种协议的所有sock为NULL
4,将所有的协议加入到inet_protocol_base中
5,dev_init()->相应网络设备的probe
6,bh_base[INET_BH].routine = inet_bh;