您的位置:首页 > 运维架构 > Linux

【linux驱动分析】之dm9000驱动分析(二):定义在板文件中的资源和设备以及几个宏

2014-04-21 16:18 555 查看
【linux驱动分析】之dm9000驱动分析(一):dm9000原理及硬件分析【linux驱动分析】之dm9000驱动分析(二):定义在板文件中的资源和设备以及几个宏【linux驱动分析】之dm9000驱动分析(三):sk_buff结构分析【linux驱动分析】之dm9000驱动分析(四):net_device结构体【linux驱动分析】之dm9000驱动分析(五):另外几个重要的结构体【linux驱动分析】之dm9000驱动分析(六):dm9000_init和dm9000_probe的实现【linux驱动分析】之dm9000驱动分析(七):dm9000的卸载挂起和恢复以及打开和停止硬件平台:友善之臂Tiny6410核心板 + DM9000EP软件平台:linux-2.6.38交叉编译器:Friendly ARM提供的arm-linux-gcc 4.5.1一、源代码(mach-mini6410.c)
1 /* Ethernet */
2 #ifdef CONFIG_DM9000
3 #define S3C64XX_PA_DM9000    (0x18000000)
4 #define S3C64XX_SZ_DM9000    SZ_1M
5 #define S3C64XX_VA_DM9000    S3C_ADDR(0x03b00300)
6
7 static struct resource dm9000_resources[] = {
8     [0] = {
9         .start        = S3C64XX_PA_DM9000,
10         .end        = S3C64XX_PA_DM9000 + 3,
11         .flags        = IORESOURCE_MEM,
12     },
13     [1] = {
14         .start        = S3C64XX_PA_DM9000 + 4,
15         .end        = S3C64XX_PA_DM9000 + S3C64XX_SZ_DM9000 - 1,
16         .flags        = IORESOURCE_MEM,
17     },
18     [2] = {
19         .start        = IRQ_EINT(7),
20         .end        = IRQ_EINT(7),
21         .flags        = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
22     },
23 };
24
25 static struct dm9000_plat_data dm9000_setup = {
26     .flags            = DM9000_PLATF_16BITONLY | DM9000_PLATF_EXT_PHY,
27     .dev_addr        = { 0x08, 0x90, 0x00, 0xa0, 0x90, 0x90 },
28 };
29
30 static struct platform_device s3c_device_dm9000 = {
31     .name            = "dm9000",
32     .id                = 0,
33     .num_resources    = ARRAY_SIZE(dm9000_resources),
34     .resource        = dm9000_resources,
35     .dev            = {
36         .platform_data = &dm9000_setup,
37     }
38 };
39
40 static int __init dm9000_set_mac(char *str) {
41     unsigned char addr[6];
42     unsigned int val;
43     int idx = 0;
44     char *p = str, *end;
45
46     while (*p && idx < 6) {
47         val = simple_strtoul(p, &end, 16);
48         if (end <= p) {
49             /* convert failed */
50             break;
51         } else {
52             addr[idx++] = val;
53             p = end;
54             if (*p == ':'|| *p == '-') {
55                 p++;
56             } else {
57                 break;
58             }
59         }
60     }
61
62     if (idx == 6) {
63         printk("Setup ethernet address to %pM\n", addr);
64         memcpy(dm9000_setup.param_addr, addr, 6);
65     }
66
67     return 1;
68 }
69
70 __setup("ethmac=", dm9000_set_mac);
71 #endif
72
73 static struct map_desc mini6410_iodesc[] = {
74     {
75         /* LCD support */
76         .virtual    = (unsigned long)S3C_VA_LCD,
77         .pfn        = __phys_to_pfn(S3C_PA_FB),
78         .length     = SZ_16K,
79         .type       = MT_DEVICE,
80     },
81 #ifdef CONFIG_DM9000           /*这里的定义不知道是做什么用的*/
82     {
83         .virtual    = (u32)S3C64XX_VA_DM9000,
84         .pfn        = __phys_to_pfn(S3C64XX_PA_DM9000),
85         .length        = S3C64XX_SZ_DM9000,
86         .type        = MT_DEVICE,
87     },
88 #endif
89 };
DM9000的设备会在
platform_add_devices(mini6410_devices, ARRAY_SIZE(mini6410_devices));
里统一注册。
二、下面分析一下上面代码中红色的宏或者函数
1、ARRAY_SIZE
#define  ARRAY_SIZE(arr)   (sizeof(arr) / sizeof( (arr)[0] )  +  __must_be_array(arr) )
它是定义在include/linux/kernel.h中的一个宏,用来计算数组中元素的个数。
__must_be_array是编译器相关的,用来防止传入的参数不是数组,比如说传入了指针,这样的话可能回编译不通过(猜测)。
2、simple_strtoul
/*** simple_strtoul - convert a string to an unsigned long* @cp: The start of the string* @endp: A pointer to the end of the parsed string will be placed here* @base: The number base to use*/unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
simple_strtoul是定义在lib/vsprintf.c中的函数,它的作用是把一个字符串转换为unsigned long型的整数,并返回。
其中的endp参数存放解析后的字符串地址,base参数,是要转换的进制数。
vsprintf.c里还定义了其他好多字符串处理的函数,具体用到时去查。
3、__setup
它是定义在include/linux/init.h中的一个宏:
#define __setup(str, fn)                    \__setup_param(str, fn, fn, 0)
其中:str是关键字,fn是关联处理函数。__setup只是告诉内核在启动时输入串中含有str时,内核要去执行fn。Str必须以“=”符结束以使parse_args更方便解析。紧随“=”后的任何文本都会作为输入传给fn。例如本例中的:__setup("ethmac=", dm9000_set_mac);关于__setup的更多分析见《__setup宏的作用》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: